diff --git a/crates/index-scheduler/src/features.rs b/crates/index-scheduler/src/features.rs index 5dbe70444..394e6518f 100644 --- a/crates/index-scheduler/src/features.rs +++ b/crates/index-scheduler/src/features.rs @@ -105,6 +105,19 @@ impl RoFeatures { .into()) } } + + pub fn check_get_task_documents_route(&self) -> Result<()> { + if self.runtime.get_task_documents_route { + Ok(()) + } else { + Err(FeatureNotEnabledError { + disabled_action: "Getting the documents of an enqueued task", + feature: "get task documents route", + issue_link: "https://github.com/orgs/meilisearch/discussions/808", + } + .into()) + } + } } impl FeatureData { diff --git a/crates/meilisearch-types/src/features.rs b/crates/meilisearch-types/src/features.rs index a11e39aa6..37a504039 100644 --- a/crates/meilisearch-types/src/features.rs +++ b/crates/meilisearch-types/src/features.rs @@ -10,6 +10,7 @@ pub struct RuntimeTogglableFeatures { pub edit_documents_by_function: bool, pub contains_filter: bool, pub network: bool, + pub get_task_documents_route: bool, } #[derive(Default, Debug, Clone, Copy)] diff --git a/crates/meilisearch/src/analytics/segment_analytics.rs b/crates/meilisearch/src/analytics/segment_analytics.rs index 388644884..63882468a 100644 --- a/crates/meilisearch/src/analytics/segment_analytics.rs +++ b/crates/meilisearch/src/analytics/segment_analytics.rs @@ -197,6 +197,7 @@ struct Infos { experimental_max_number_of_batched_tasks: usize, experimental_limit_batched_tasks_total_size: u64, experimental_network: bool, + experimental_get_task_documents_route: bool, gpu_enabled: bool, db_path: bool, import_dump: bool, @@ -288,6 +289,7 @@ impl Infos { edit_documents_by_function, contains_filter, network, + get_task_documents_route, } = features; // We're going to override every sensible information. @@ -306,6 +308,7 @@ impl Infos { experimental_enable_logs_route: experimental_enable_logs_route | logs_route, experimental_reduce_indexing_memory_usage, experimental_network: network, + experimental_get_task_documents_route: get_task_documents_route, gpu_enabled: meilisearch_types::milli::vector::is_cuda_enabled(), db_path: db_path != PathBuf::from("./data.ms"), import_dump: import_dump.is_some(), diff --git a/crates/meilisearch/src/routes/features.rs b/crates/meilisearch/src/routes/features.rs index e30bc8e8e..402bc11ae 100644 --- a/crates/meilisearch/src/routes/features.rs +++ b/crates/meilisearch/src/routes/features.rs @@ -51,6 +51,7 @@ pub fn configure(cfg: &mut web::ServiceConfig) { edit_documents_by_function: Some(false), contains_filter: Some(false), network: Some(false), + get_task_documents_route: Some(false), })), (status = 401, description = "The authorization header is missing", body = ResponseError, content_type = "application/json", example = json!( { @@ -91,6 +92,8 @@ pub struct RuntimeTogglableFeatures { pub contains_filter: Option, #[deserr(default)] pub network: Option, + #[deserr(default)] + pub get_task_documents_route: Option, } impl From for RuntimeTogglableFeatures { @@ -101,6 +104,7 @@ impl From for RuntimeTogg edit_documents_by_function, contains_filter, network, + get_task_documents_route, } = value; Self { @@ -109,6 +113,7 @@ impl From for RuntimeTogg edit_documents_by_function: Some(edit_documents_by_function), contains_filter: Some(contains_filter), network: Some(network), + get_task_documents_route: Some(get_task_documents_route), } } } @@ -120,6 +125,7 @@ pub struct PatchExperimentalFeatureAnalytics { edit_documents_by_function: bool, contains_filter: bool, network: bool, + get_task_documents_route: bool, } impl Aggregate for PatchExperimentalFeatureAnalytics { @@ -134,6 +140,7 @@ impl Aggregate for PatchExperimentalFeatureAnalytics { edit_documents_by_function: new.edit_documents_by_function, contains_filter: new.contains_filter, network: new.network, + get_task_documents_route: new.get_task_documents_route, }) } @@ -157,6 +164,7 @@ impl Aggregate for PatchExperimentalFeatureAnalytics { edit_documents_by_function: Some(false), contains_filter: Some(false), network: Some(false), + get_task_documents_route: Some(false), })), (status = 401, description = "The authorization header is missing", body = ResponseError, content_type = "application/json", example = json!( { @@ -190,6 +198,10 @@ async fn patch_features( .unwrap_or(old_features.edit_documents_by_function), contains_filter: new_features.0.contains_filter.unwrap_or(old_features.contains_filter), network: new_features.0.network.unwrap_or(old_features.network), + get_task_documents_route: new_features + .0 + .get_task_documents_route + .unwrap_or(old_features.get_task_documents_route), }; // explicitly destructure for analytics rather than using the `Serialize` implementation, because @@ -201,6 +213,7 @@ async fn patch_features( edit_documents_by_function, contains_filter, network, + get_task_documents_route, } = new_features; analytics.publish( @@ -210,6 +223,7 @@ async fn patch_features( edit_documents_by_function, contains_filter, network, + get_task_documents_route, }, &req, ); diff --git a/crates/meilisearch/src/routes/tasks.rs b/crates/meilisearch/src/routes/tasks.rs index bd945a945..3ef116dd7 100644 --- a/crates/meilisearch/src/routes/tasks.rs +++ b/crates/meilisearch/src/routes/tasks.rs @@ -679,6 +679,7 @@ async fn get_task_documents_file( index_scheduler: GuardedData, Data>, task_uid: web::Path, ) -> Result { + index_scheduler.features().check_get_task_documents_route()?; let task_uid_string = task_uid.into_inner(); let task_uid: TaskId = match task_uid_string.parse() { diff --git a/crates/meilisearch/tests/dumps/mod.rs b/crates/meilisearch/tests/dumps/mod.rs index 2b4c32cc7..6102a2817 100644 --- a/crates/meilisearch/tests/dumps/mod.rs +++ b/crates/meilisearch/tests/dumps/mod.rs @@ -1909,7 +1909,8 @@ async fn import_dump_v6_containing_experimental_features() { "logsRoute": false, "editDocumentsByFunction": false, "containsFilter": false, - "network": false + "network": false, + "getTaskDocumentsRoute": false } "###); @@ -2071,7 +2072,8 @@ async fn generate_and_import_dump_containing_vectors() { "logsRoute": false, "editDocumentsByFunction": false, "containsFilter": false, - "network": false + "network": false, + "getTaskDocumentsRoute": false } "###); diff --git a/crates/meilisearch/tests/features/mod.rs b/crates/meilisearch/tests/features/mod.rs index 36559daf6..d417efa4c 100644 --- a/crates/meilisearch/tests/features/mod.rs +++ b/crates/meilisearch/tests/features/mod.rs @@ -22,7 +22,8 @@ async fn experimental_features() { "logsRoute": false, "editDocumentsByFunction": false, "containsFilter": false, - "network": false + "network": false, + "getTaskDocumentsRoute": false } "###); @@ -35,7 +36,8 @@ async fn experimental_features() { "logsRoute": false, "editDocumentsByFunction": false, "containsFilter": false, - "network": false + "network": false, + "getTaskDocumentsRoute": false } "###); @@ -48,7 +50,8 @@ async fn experimental_features() { "logsRoute": false, "editDocumentsByFunction": false, "containsFilter": false, - "network": false + "network": false, + "getTaskDocumentsRoute": false } "###); @@ -62,7 +65,8 @@ async fn experimental_features() { "logsRoute": false, "editDocumentsByFunction": false, "containsFilter": false, - "network": false + "network": false, + "getTaskDocumentsRoute": false } "###); @@ -76,7 +80,8 @@ async fn experimental_features() { "logsRoute": false, "editDocumentsByFunction": false, "containsFilter": false, - "network": false + "network": false, + "getTaskDocumentsRoute": false } "###); } @@ -97,7 +102,8 @@ async fn experimental_feature_metrics() { "logsRoute": false, "editDocumentsByFunction": false, "containsFilter": false, - "network": false + "network": false, + "getTaskDocumentsRoute": false } "###); @@ -152,7 +158,7 @@ async fn errors() { meili_snap::snapshot!(code, @"400 Bad Request"); meili_snap::snapshot!(meili_snap::json_string!(response), @r###" { - "message": "Unknown field `NotAFeature`: expected one of `metrics`, `logsRoute`, `editDocumentsByFunction`, `containsFilter`, `network`", + "message": "Unknown field `NotAFeature`: expected one of `metrics`, `logsRoute`, `editDocumentsByFunction`, `containsFilter`, `network`, `getTaskDocumentsRoute`", "code": "bad_request", "type": "invalid_request", "link": "https://docs.meilisearch.com/errors#bad_request"