diff --git a/meilisearch-http/src/task.rs b/meilisearch-http/src/task.rs index 7179b10db..c8e269e56 100644 --- a/meilisearch-http/src/task.rs +++ b/meilisearch-http/src/task.rs @@ -137,7 +137,7 @@ fn serialize_duration( #[serde(rename_all = "camelCase")] pub struct TaskView { uid: TaskId, - index_uid: String, + index_uid: Option, status: TaskStatus, #[serde(rename = "type")] task_type: TaskType, @@ -313,7 +313,7 @@ impl From for TaskView { Self { uid: id, - index_uid: index_uid.into_inner(), + index_uid: index_uid.map(|u| u.into_inner()), status, task_type, details, @@ -342,7 +342,7 @@ impl From> for TaskListView { #[serde(rename_all = "camelCase")] pub struct SummarizedTaskView { uid: TaskId, - index_uid: String, + index_uid: Option, status: TaskStatus, #[serde(rename = "type")] task_type: TaskType, @@ -365,7 +365,7 @@ impl From for SummarizedTaskView { Self { uid: other.id, - index_uid: other.index_uid.to_string(), + index_uid: other.index_uid.map(|u| u.into_inner()), status: TaskStatus::Enqueued, task_type: other.content.into(), enqueued_at, diff --git a/meilisearch-lib/src/index_controller/dump_actor/compat/v3.rs b/meilisearch-lib/src/index_controller/dump_actor/compat/v3.rs index 7cd670bad..befd70963 100644 --- a/meilisearch-lib/src/index_controller/dump_actor/compat/v3.rs +++ b/meilisearch-lib/src/index_controller/dump_actor/compat/v3.rs @@ -187,7 +187,7 @@ impl From<(UpdateStatus, String, TaskId)> for Task { // Dummy task let mut task = Task { id: task_id, - index_uid: IndexUid::new(uid).unwrap(), + index_uid: Some(IndexUid::new(uid).unwrap()), content: TaskContent::IndexDeletion, events: Vec::new(), }; diff --git a/meilisearch-lib/src/index_controller/mod.rs b/meilisearch-lib/src/index_controller/mod.rs index a302f12da..7ba91dfca 100644 --- a/meilisearch-lib/src/index_controller/mod.rs +++ b/meilisearch-lib/src/index_controller/mod.rs @@ -419,7 +419,7 @@ where Update::UpdateIndex { primary_key } => TaskContent::IndexUpdate { primary_key }, }; - let task = self.task_store.register(uid, content).await?; + let task = self.task_store.register(Some(uid), content).await?; self.scheduler.read().await.notify(); Ok(task) @@ -569,7 +569,12 @@ where // Check if the currently indexing update is from our index. let is_indexing = processing_tasks .first() - .map(|task| task.index_uid.as_str() == uid) + .map(|task| { + task.index_uid + .as_ref() + .map(|u| u.as_str() == uid) + .unwrap_or(false) + }) .unwrap_or_default(); let index = self.index_resolver.get_index(uid).await?; @@ -605,7 +610,7 @@ where // Check if the currently indexing update is from our index. stats.is_indexing = processing_tasks .first() - .map(|p| p.index_uid.as_str() == index_uid) + .and_then(|p| p.index_uid.as_ref().map(|u| u.as_str() == index_uid)) .or(Some(false)); indexes.insert(index_uid, stats); diff --git a/meilisearch-lib/src/index_resolver/mod.rs b/meilisearch-lib/src/index_resolver/mod.rs index 8ca3efdc6..9db808d3f 100644 --- a/meilisearch-lib/src/index_resolver/mod.rs +++ b/meilisearch-lib/src/index_resolver/mod.rs @@ -204,7 +204,7 @@ where match batch.tasks.first() { Some(Task { - index_uid, + index_uid: Some(ref index_uid), id, content: TaskContent::DocumentAddition { @@ -285,7 +285,7 @@ where TaskContent::DocumentAddition { .. } => panic!("updates should be handled by batch"), TaskContent::DocumentDeletion(DocumentDeletion::Ids(ids)) => { let ids = ids.clone(); - let index = self.get_index(index_uid.into_inner()).await?; + let index = self.get_index(index_uid.unwrap().into_inner()).await?; let DocumentDeletionResult { deleted_documents, .. @@ -294,7 +294,7 @@ where Ok(TaskResult::DocumentDeletion { deleted_documents }) } TaskContent::DocumentDeletion(DocumentDeletion::Clear) => { - let index = self.get_index(index_uid.into_inner()).await?; + let index = self.get_index(index_uid.unwrap().into_inner()).await?; let deleted_documents = spawn_blocking(move || -> IndexResult { let number_documents = index.stats()?.number_of_documents; index.clear_documents()?; @@ -310,9 +310,10 @@ where allow_index_creation, } => { let index = if *is_deletion || !*allow_index_creation { - self.get_index(index_uid.into_inner()).await? + self.get_index(index_uid.unwrap().into_inner()).await? } else { - self.get_or_create_index(index_uid, task.id).await? + self.get_or_create_index(index_uid.unwrap(), task.id) + .await? }; let settings = settings.clone(); @@ -321,7 +322,7 @@ where Ok(TaskResult::Other) } TaskContent::IndexDeletion => { - let index = self.delete_index(index_uid.into_inner()).await?; + let index = self.delete_index(index_uid.unwrap().into_inner()).await?; let deleted_documents = spawn_blocking(move || -> IndexResult { Ok(index.stats()?.number_of_documents) @@ -331,7 +332,7 @@ where Ok(TaskResult::ClearAll { deleted_documents }) } TaskContent::IndexCreation { primary_key } => { - let index = self.create_index(index_uid, task.id).await?; + let index = self.create_index(index_uid.unwrap(), task.id).await?; if let Some(primary_key) = primary_key { let primary_key = primary_key.clone(); @@ -341,7 +342,7 @@ where Ok(TaskResult::Other) } TaskContent::IndexUpdate { primary_key } => { - let index = self.get_index(index_uid.into_inner()).await?; + let index = self.get_index(index_uid.unwrap().into_inner()).await?; if let Some(primary_key) = primary_key { let primary_key = primary_key.clone(); @@ -503,7 +504,7 @@ mod test { proptest! { #[test] fn test_process_task( - task in any::(), + task in any::().prop_filter("uid must be Some", |t| t.index_uid.is_some()), index_exists in any::(), index_op_fails in any::(), any_int in any::(), diff --git a/meilisearch-lib/src/tasks/scheduler.rs b/meilisearch-lib/src/tasks/scheduler.rs index 0e540a646..94de2a5fd 100644 --- a/meilisearch-lib/src/tasks/scheduler.rs +++ b/meilisearch-lib/src/tasks/scheduler.rs @@ -125,7 +125,8 @@ struct TaskQueue { impl TaskQueue { fn insert(&mut self, task: Task) { - let uid = task.index_uid.into_inner(); + // TODO(marin): The index uid should be remaped to a task queue identifier here + let uid = task.index_uid.unwrap().into_inner(); let id = task.id; let kind = match task.content { TaskContent::DocumentAddition { @@ -443,7 +444,7 @@ mod test { fn gen_task(id: TaskId, index_uid: &str, content: TaskContent) -> Task { Task { id, - index_uid: IndexUid::new_unchecked(index_uid), + index_uid: Some(IndexUid::new_unchecked(index_uid)), content, events: vec![], } diff --git a/meilisearch-lib/src/tasks/task.rs b/meilisearch-lib/src/tasks/task.rs index ecbd4ca62..d7a73a2ae 100644 --- a/meilisearch-lib/src/tasks/task.rs +++ b/meilisearch-lib/src/tasks/task.rs @@ -74,7 +74,11 @@ pub enum TaskEvent { #[cfg_attr(test, derive(proptest_derive::Arbitrary))] pub struct Task { pub id: TaskId, - pub index_uid: IndexUid, + /// The name of the index the task is targeting. If it isn't targeting any idex (i.e Dump task) + /// then this is None + // TODO: when next forward breaking dumps, it would be a good idea to move this field inside of + // the TaskContent. + pub index_uid: Option, pub content: TaskContent, pub events: Vec, } diff --git a/meilisearch-lib/src/tasks/task_store/mod.rs b/meilisearch-lib/src/tasks/task_store/mod.rs index bdcd13f37..bde0f6360 100644 --- a/meilisearch-lib/src/tasks/task_store/mod.rs +++ b/meilisearch-lib/src/tasks/task_store/mod.rs @@ -30,10 +30,14 @@ pub struct TaskFilter { impl TaskFilter { fn pass(&self, task: &Task) -> bool { - self.indexes - .as_ref() - .map(|indexes| indexes.contains(&*task.index_uid)) - .unwrap_or(true) + match task.index_uid { + Some(ref index_uid) => self + .indexes + .as_ref() + .map(|indexes| indexes.contains(index_uid.as_str())) + .unwrap_or(true), + None => false, + } } /// Adds an index to the filter, so the filter must match this index. @@ -66,7 +70,11 @@ impl TaskStore { Ok(Self { store }) } - pub async fn register(&self, index_uid: IndexUid, content: TaskContent) -> Result { + pub async fn register( + &self, + index_uid: Option, + content: TaskContent, + ) -> Result { debug!("registering update: {:?}", content); let store = self.store.clone(); let task = tokio::task::spawn_blocking(move || -> Result { @@ -305,7 +313,11 @@ pub mod test { } } - pub async fn register(&self, index_uid: IndexUid, content: TaskContent) -> Result { + pub async fn register( + &self, + index_uid: Option, + content: TaskContent, + ) -> Result { match self { Self::Real(s) => s.register(index_uid, content).await, Self::Mock(_m) => todo!(), @@ -335,7 +347,7 @@ pub mod test { let gen_task = |id: TaskId| Task { id, - index_uid: IndexUid::new_unchecked("test"), + index_uid: Some(IndexUid::new_unchecked("test")), content: TaskContent::IndexCreation { primary_key: None }, events: Vec::new(), }; diff --git a/meilisearch-lib/src/tasks/task_store/store.rs b/meilisearch-lib/src/tasks/task_store/store.rs index 4ff986d8b..912047d1e 100644 --- a/meilisearch-lib/src/tasks/task_store/store.rs +++ b/meilisearch-lib/src/tasks/task_store/store.rs @@ -109,7 +109,8 @@ impl Store { pub fn put(&self, txn: &mut RwTxn, task: &Task) -> Result<()> { self.tasks.put(txn, &BEU64::new(task.id), task)?; self.uids_task_ids - .put(txn, &(&task.index_uid, task.id), &())?; + // TODO(marin): The index uid should be remaped to a task queue identifier here + .put(txn, &(&task.index_uid.as_ref().unwrap(), task.id), &())?; Ok(()) } @@ -325,7 +326,7 @@ pub mod test { let tasks = (0..100) .map(|_| Task { id: rand::random(), - index_uid: IndexUid::new_unchecked("test"), + index_uid: Some(IndexUid::new_unchecked("test")), content: TaskContent::IndexDeletion, events: vec![], }) @@ -356,14 +357,14 @@ pub mod test { let task_1 = Task { id: 1, - index_uid: IndexUid::new_unchecked("test"), + index_uid: Some(IndexUid::new_unchecked("test")), content: TaskContent::IndexDeletion, events: vec![], }; let task_2 = Task { id: 0, - index_uid: IndexUid::new_unchecked("test1"), + index_uid: Some(IndexUid::new_unchecked("test1")), content: TaskContent::IndexDeletion, events: vec![], }; @@ -379,18 +380,28 @@ pub mod test { txn.abort().unwrap(); assert_eq!(tasks.len(), 1); - assert_eq!(&*tasks.first().unwrap().index_uid, "test"); + assert_eq!( + tasks + .first() + .as_ref() + .unwrap() + .index_uid + .as_ref() + .unwrap() + .as_str(), + "test" + ); // same thing but invert the ids let task_1 = Task { id: 0, - index_uid: IndexUid::new_unchecked("test"), + index_uid: Some(IndexUid::new_unchecked("test")), content: TaskContent::IndexDeletion, events: vec![], }; let task_2 = Task { id: 1, - index_uid: IndexUid::new_unchecked("test1"), + index_uid: Some(IndexUid::new_unchecked("test1")), content: TaskContent::IndexDeletion, events: vec![], }; @@ -405,7 +416,17 @@ pub mod test { let tasks = store.list_tasks(&txn, None, Some(filter), None).unwrap(); assert_eq!(tasks.len(), 1); - assert_eq!(&*tasks.first().unwrap().index_uid, "test"); + assert_eq!( + &*tasks + .first() + .as_ref() + .unwrap() + .index_uid + .as_ref() + .unwrap() + .as_str(), + "test" + ); } proptest! {