diff --git a/src/data/mod.rs b/src/data/mod.rs index 0b57f9a55..f2798c868 100644 --- a/src/data/mod.rs +++ b/src/data/mod.rs @@ -9,8 +9,8 @@ use std::sync::Arc; use sha2::Digest; -use crate::index_controller::{IndexController, IndexMetadata, Settings, IndexSettings}; -use crate::index_controller::actor_index_controller::ActorIndexController; +use crate::index_controller::{IndexMetadata, Settings, IndexSettings}; +use crate::index_controller::actor_index_controller::IndexController; use crate::option::Opt; #[derive(Clone)] @@ -26,9 +26,8 @@ impl Deref for Data { } } -#[derive(Clone)] pub struct DataInner { - pub index_controller: Arc, + pub index_controller: IndexController, pub api_keys: ApiKeys, options: Opt, } @@ -62,8 +61,7 @@ impl Data { let path = options.db_path.clone(); //let indexer_opts = options.indexer_options.clone(); create_dir_all(&path)?; - let index_controller = ActorIndexController::new(&path); - let index_controller = Arc::new(index_controller); + let index_controller = IndexController::new(&path); let mut api_keys = ApiKeys { master: options.clone().master_key, diff --git a/src/index_controller/actor_index_controller/mod.rs b/src/index_controller/actor_index_controller/mod.rs index 58e58a45a..34fcf55f0 100644 --- a/src/index_controller/actor_index_controller/mod.rs +++ b/src/index_controller/actor_index_controller/mod.rs @@ -7,7 +7,6 @@ mod update_handler; use std::path::Path; use tokio::sync::{mpsc, oneshot}; -use super::IndexController; use uuid::Uuid; use super::IndexMetadata; use futures::stream::StreamExt; @@ -16,21 +15,12 @@ use super::UpdateMeta; use crate::data::{SearchResult, SearchQuery}; use actix_web::web::Bytes; -pub struct ActorIndexController { +pub struct IndexController { uuid_resolver: uuid_resolver::UuidResolverHandle, index_handle: index_actor::IndexActorHandle, update_handle: update_actor::UpdateActorHandle, } -impl ActorIndexController { - pub fn new(path: impl AsRef) -> Self { - let uuid_resolver = uuid_resolver::UuidResolverHandle::new(); - let index_actor = index_actor::IndexActorHandle::new(); - let update_handle = update_actor::UpdateActorHandle::new(index_actor.clone(), &path); - Self { uuid_resolver, index_handle: index_actor, update_handle } - } -} - enum IndexControllerMsg { CreateIndex { uuid: Uuid, @@ -40,9 +30,15 @@ enum IndexControllerMsg { Shutdown, } -#[async_trait::async_trait(?Send)] -impl IndexController for ActorIndexController { - async fn add_documents( +impl IndexController { + pub fn new(path: impl AsRef) -> Self { + let uuid_resolver = uuid_resolver::UuidResolverHandle::new(); + let index_actor = index_actor::IndexActorHandle::new(); + let update_handle = update_actor::UpdateActorHandle::new(index_actor.clone(), &path); + Self { uuid_resolver, index_handle: index_actor, update_handle } + } + + pub async fn add_documents( &self, index: String, method: milli::update::IndexDocumentsMethod, @@ -78,7 +74,7 @@ impl IndexController for ActorIndexController { todo!() } - async fn create_index(&self, index_settings: super::IndexSettings) -> anyhow::Result { + pub async fn create_index(&self, index_settings: super::IndexSettings) -> anyhow::Result { let super::IndexSettings { name, primary_key } = index_settings; let uuid = self.uuid_resolver.create(name.unwrap()).await?; let index_meta = self.index_handle.create_index(uuid, primary_key).await?; @@ -93,7 +89,7 @@ impl IndexController for ActorIndexController { todo!() } - fn index(&self, name: String) -> anyhow::Result>> { + pub fn index(&self, name: String) -> anyhow::Result>> { todo!() } @@ -105,7 +101,7 @@ impl IndexController for ActorIndexController { todo!() } - fn list_indexes(&self) -> anyhow::Result> { + pub fn list_indexes(&self) -> anyhow::Result> { todo!() } @@ -113,7 +109,7 @@ impl IndexController for ActorIndexController { todo!() } - async fn search(&self, name: String, query: SearchQuery) -> anyhow::Result { + pub async fn search(&self, name: String, query: SearchQuery) -> anyhow::Result { let uuid = self.uuid_resolver.resolve(name).await.unwrap().unwrap(); let result = self.index_handle.search(uuid, query).await?; Ok(result) diff --git a/src/index_controller/mod.rs b/src/index_controller/mod.rs index c3a09b2aa..fbe7a161d 100644 --- a/src/index_controller/mod.rs +++ b/src/index_controller/mod.rs @@ -1,20 +1,14 @@ pub mod actor_index_controller; -//mod local_index_controller; mod updates; use std::collections::HashMap; use std::num::NonZeroUsize; -use std::sync::Arc; use anyhow::Result; use chrono::{DateTime, Utc}; -use milli::Index; use milli::update::{IndexDocumentsMethod, UpdateFormat, DocumentAdditionResult}; use serde::{Serialize, Deserialize, de::Deserializer}; use uuid::Uuid; -use actix_web::web::Payload; -use crate::data::SearchResult; -use crate::data::SearchQuery; pub use updates::{Processed, Processing, Failed}; @@ -109,165 +103,3 @@ pub struct IndexSettings { pub name: Option, pub primary_key: Option, } - -/// The `IndexController` is in charge of the access to the underlying indices. It splits the logic -/// for read access which is provided thanks to an handle to the index, and write access which must -/// be provided. This allows the implementer to define the behaviour of write accesses to the -/// indices, and abstract the scheduling of the updates. The implementer must be able to provide an -/// instance of `IndexStore` -#[async_trait::async_trait(?Send)] -pub trait IndexController { - - /* - * Write operations - * - * Logic for the write operation need to be provided by the implementer, since they can be made - * asynchronous thanks to an update_store for example. - * - * */ - - /// Perform document addition on the database. If the provided index does not exist, it will be - /// created when the addition is applied to the index. - async fn add_documents( - &self, - index: String, - method: IndexDocumentsMethod, - format: UpdateFormat, - data: Payload, - primary_key: Option, - ) -> anyhow::Result; - - async fn search(&self, name: String, query: SearchQuery) -> Result; - - /// Clear all documents in the given index. - fn clear_documents(&self, index: String) -> anyhow::Result; - - /// Delete all documents in `document_ids`. - fn delete_documents(&self, index: String, document_ids: Vec) -> anyhow::Result; - - /// Updates an index settings. If the index does not exist, it will be created when the update - /// is applied to the index. - fn update_settings(&self, index_uid: String, settings: Settings) -> anyhow::Result; - - /// Create an index with the given `index_uid`. - async fn create_index(&self, index_settings: IndexSettings) -> Result; - - /// Delete index with the given `index_uid`, attempting to close it beforehand. - fn delete_index(&self, index_uid: String) -> Result<()>; - - /// Swap two indexes, concretely, it simply swaps the index the names point to. - fn swap_indices(&self, index1_uid: String, index2_uid: String) -> Result<()>; - - /// Returns, if it exists, the `Index` with the povided name. - fn index(&self, name: String) -> anyhow::Result>>; - - /// Returns the udpate status an update - fn update_status(&self, index: String, id: u64) -> anyhow::Result>; - - /// Returns all the udpate status for an index - fn all_update_status(&self, index: String) -> anyhow::Result>; - - /// List all the indexes - fn list_indexes(&self) -> anyhow::Result>; - - fn update_index(&self, name: String, index_settings: IndexSettings) -> anyhow::Result; -} - - -#[cfg(test)] -#[macro_use] -pub(crate) mod test { - use super::*; - - #[macro_export] - macro_rules! make_index_controller_tests { - ($controller_buider:block) => { - #[test] - fn test_create_and_list_indexes() { - crate::index_controller::test::create_and_list_indexes($controller_buider); - } - - #[test] - fn test_create_index_with_no_name_is_error() { - crate::index_controller::test::create_index_with_no_name_is_error($controller_buider); - } - - #[test] - fn test_update_index() { - crate::index_controller::test::update_index($controller_buider); - } - }; - } - - pub(crate) fn create_and_list_indexes(controller: impl IndexController) { - let settings1 = IndexSettings { - name: Some(String::from("test_index")), - primary_key: None, - }; - - let settings2 = IndexSettings { - name: Some(String::from("test_index2")), - primary_key: Some(String::from("foo")), - }; - - controller.create_index(settings1).unwrap(); - controller.create_index(settings2).unwrap(); - - let indexes = controller.list_indexes().unwrap(); - assert_eq!(indexes.len(), 2); - assert_eq!(indexes[0].uid, "test_index"); - assert_eq!(indexes[1].uid, "test_index2"); - assert_eq!(indexes[1].primary_key.clone().unwrap(), "foo"); - } - - pub(crate) fn create_index_with_no_name_is_error(controller: impl IndexController) { - let settings = IndexSettings { - name: None, - primary_key: None, - }; - assert!(controller.create_index(settings).is_err()); - } - - pub(crate) fn update_index(controller: impl IndexController) { - - let settings = IndexSettings { - name: Some(String::from("test")), - primary_key: None, - }; - - assert!(controller.create_index(settings).is_ok()); - - // perform empty update returns index meta unchanged - let settings = IndexSettings { - name: None, - primary_key: None, - }; - - let result = controller.update_index("test", settings).unwrap(); - assert_eq!(result.uid, "test"); - assert_eq!(result.created_at, result.updated_at); - assert!(result.primary_key.is_none()); - - // Changing the name trigger an error - let settings = IndexSettings { - name: Some(String::from("bar")), - primary_key: None, - }; - - assert!(controller.update_index("test", settings).is_err()); - - // Update primary key - let settings = IndexSettings { - name: None, - primary_key: Some(String::from("foo")), - }; - - let result = controller.update_index("test", settings.clone()).unwrap(); - assert_eq!(result.uid, "test"); - assert!(result.created_at < result.updated_at); - assert_eq!(result.primary_key.unwrap(), "foo"); - - // setting the primary key again is an error - assert!(controller.update_index("test", settings).is_err()); - } -}