mirror of
https://github.com/meilisearch/MeiliSearch
synced 2024-12-25 14:10:06 +01:00
remove IndexController interface
This commit is contained in:
parent
9aca6fab88
commit
7c7143d435
@ -9,8 +9,8 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use sha2::Digest;
|
use sha2::Digest;
|
||||||
|
|
||||||
use crate::index_controller::{IndexController, IndexMetadata, Settings, IndexSettings};
|
use crate::index_controller::{IndexMetadata, Settings, IndexSettings};
|
||||||
use crate::index_controller::actor_index_controller::ActorIndexController;
|
use crate::index_controller::actor_index_controller::IndexController;
|
||||||
use crate::option::Opt;
|
use crate::option::Opt;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -26,9 +26,8 @@ impl Deref for Data {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct DataInner {
|
pub struct DataInner {
|
||||||
pub index_controller: Arc<dyn IndexController + Send + Sync>,
|
pub index_controller: IndexController,
|
||||||
pub api_keys: ApiKeys,
|
pub api_keys: ApiKeys,
|
||||||
options: Opt,
|
options: Opt,
|
||||||
}
|
}
|
||||||
@ -62,8 +61,7 @@ impl Data {
|
|||||||
let path = options.db_path.clone();
|
let path = options.db_path.clone();
|
||||||
//let indexer_opts = options.indexer_options.clone();
|
//let indexer_opts = options.indexer_options.clone();
|
||||||
create_dir_all(&path)?;
|
create_dir_all(&path)?;
|
||||||
let index_controller = ActorIndexController::new(&path);
|
let index_controller = IndexController::new(&path);
|
||||||
let index_controller = Arc::new(index_controller);
|
|
||||||
|
|
||||||
let mut api_keys = ApiKeys {
|
let mut api_keys = ApiKeys {
|
||||||
master: options.clone().master_key,
|
master: options.clone().master_key,
|
||||||
|
@ -7,7 +7,6 @@ mod update_handler;
|
|||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use tokio::sync::{mpsc, oneshot};
|
use tokio::sync::{mpsc, oneshot};
|
||||||
use super::IndexController;
|
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use super::IndexMetadata;
|
use super::IndexMetadata;
|
||||||
use futures::stream::StreamExt;
|
use futures::stream::StreamExt;
|
||||||
@ -16,21 +15,12 @@ use super::UpdateMeta;
|
|||||||
use crate::data::{SearchResult, SearchQuery};
|
use crate::data::{SearchResult, SearchQuery};
|
||||||
use actix_web::web::Bytes;
|
use actix_web::web::Bytes;
|
||||||
|
|
||||||
pub struct ActorIndexController {
|
pub struct IndexController {
|
||||||
uuid_resolver: uuid_resolver::UuidResolverHandle,
|
uuid_resolver: uuid_resolver::UuidResolverHandle,
|
||||||
index_handle: index_actor::IndexActorHandle,
|
index_handle: index_actor::IndexActorHandle,
|
||||||
update_handle: update_actor::UpdateActorHandle<Bytes>,
|
update_handle: update_actor::UpdateActorHandle<Bytes>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ActorIndexController {
|
|
||||||
pub fn new(path: impl AsRef<Path>) -> 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 {
|
enum IndexControllerMsg {
|
||||||
CreateIndex {
|
CreateIndex {
|
||||||
uuid: Uuid,
|
uuid: Uuid,
|
||||||
@ -40,9 +30,15 @@ enum IndexControllerMsg {
|
|||||||
Shutdown,
|
Shutdown,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
impl IndexController {
|
||||||
impl IndexController for ActorIndexController {
|
pub fn new(path: impl AsRef<Path>) -> Self {
|
||||||
async fn add_documents(
|
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,
|
&self,
|
||||||
index: String,
|
index: String,
|
||||||
method: milli::update::IndexDocumentsMethod,
|
method: milli::update::IndexDocumentsMethod,
|
||||||
@ -78,7 +74,7 @@ impl IndexController for ActorIndexController {
|
|||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn create_index(&self, index_settings: super::IndexSettings) -> anyhow::Result<super::IndexMetadata> {
|
pub async fn create_index(&self, index_settings: super::IndexSettings) -> anyhow::Result<super::IndexMetadata> {
|
||||||
let super::IndexSettings { name, primary_key } = index_settings;
|
let super::IndexSettings { name, primary_key } = index_settings;
|
||||||
let uuid = self.uuid_resolver.create(name.unwrap()).await?;
|
let uuid = self.uuid_resolver.create(name.unwrap()).await?;
|
||||||
let index_meta = self.index_handle.create_index(uuid, primary_key).await?;
|
let index_meta = self.index_handle.create_index(uuid, primary_key).await?;
|
||||||
@ -93,7 +89,7 @@ impl IndexController for ActorIndexController {
|
|||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn index(&self, name: String) -> anyhow::Result<Option<std::sync::Arc<milli::Index>>> {
|
pub fn index(&self, name: String) -> anyhow::Result<Option<std::sync::Arc<milli::Index>>> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,7 +101,7 @@ impl IndexController for ActorIndexController {
|
|||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn list_indexes(&self) -> anyhow::Result<Vec<super::IndexMetadata>> {
|
pub fn list_indexes(&self) -> anyhow::Result<Vec<super::IndexMetadata>> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,7 +109,7 @@ impl IndexController for ActorIndexController {
|
|||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn search(&self, name: String, query: SearchQuery) -> anyhow::Result<SearchResult> {
|
pub async fn search(&self, name: String, query: SearchQuery) -> anyhow::Result<SearchResult> {
|
||||||
let uuid = self.uuid_resolver.resolve(name).await.unwrap().unwrap();
|
let uuid = self.uuid_resolver.resolve(name).await.unwrap().unwrap();
|
||||||
let result = self.index_handle.search(uuid, query).await?;
|
let result = self.index_handle.search(uuid, query).await?;
|
||||||
Ok(result)
|
Ok(result)
|
||||||
|
@ -1,20 +1,14 @@
|
|||||||
pub mod actor_index_controller;
|
pub mod actor_index_controller;
|
||||||
//mod local_index_controller;
|
|
||||||
mod updates;
|
mod updates;
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::num::NonZeroUsize;
|
use std::num::NonZeroUsize;
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use milli::Index;
|
|
||||||
use milli::update::{IndexDocumentsMethod, UpdateFormat, DocumentAdditionResult};
|
use milli::update::{IndexDocumentsMethod, UpdateFormat, DocumentAdditionResult};
|
||||||
use serde::{Serialize, Deserialize, de::Deserializer};
|
use serde::{Serialize, Deserialize, de::Deserializer};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use actix_web::web::Payload;
|
|
||||||
use crate::data::SearchResult;
|
|
||||||
use crate::data::SearchQuery;
|
|
||||||
|
|
||||||
pub use updates::{Processed, Processing, Failed};
|
pub use updates::{Processed, Processing, Failed};
|
||||||
|
|
||||||
@ -109,165 +103,3 @@ pub struct IndexSettings {
|
|||||||
pub name: Option<String>,
|
pub name: Option<String>,
|
||||||
pub primary_key: Option<String>,
|
pub primary_key: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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<String>,
|
|
||||||
) -> anyhow::Result<UpdateStatus>;
|
|
||||||
|
|
||||||
async fn search(&self, name: String, query: SearchQuery) -> Result<SearchResult>;
|
|
||||||
|
|
||||||
/// Clear all documents in the given index.
|
|
||||||
fn clear_documents(&self, index: String) -> anyhow::Result<UpdateStatus>;
|
|
||||||
|
|
||||||
/// Delete all documents in `document_ids`.
|
|
||||||
fn delete_documents(&self, index: String, document_ids: Vec<String>) -> anyhow::Result<UpdateStatus>;
|
|
||||||
|
|
||||||
/// 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<UpdateStatus>;
|
|
||||||
|
|
||||||
/// Create an index with the given `index_uid`.
|
|
||||||
async fn create_index(&self, index_settings: IndexSettings) -> Result<IndexMetadata>;
|
|
||||||
|
|
||||||
/// 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<Option<Arc<Index>>>;
|
|
||||||
|
|
||||||
/// Returns the udpate status an update
|
|
||||||
fn update_status(&self, index: String, id: u64) -> anyhow::Result<Option<UpdateStatus>>;
|
|
||||||
|
|
||||||
/// Returns all the udpate status for an index
|
|
||||||
fn all_update_status(&self, index: String) -> anyhow::Result<Vec<UpdateStatus>>;
|
|
||||||
|
|
||||||
/// List all the indexes
|
|
||||||
fn list_indexes(&self) -> anyhow::Result<Vec<IndexMetadata>>;
|
|
||||||
|
|
||||||
fn update_index(&self, name: String, index_settings: IndexSettings) -> anyhow::Result<IndexMetadata>;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#[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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user