2021-12-02 23:03:26 +08:00
|
|
|
use std::path::PathBuf;
|
|
|
|
|
|
|
|
use meilisearch_error::ResponseError;
|
|
|
|
use milli::update::{DocumentAdditionResult, IndexDocumentsMethod};
|
|
|
|
use serde::{Deserialize, Serialize};
|
2022-02-14 22:32:41 +08:00
|
|
|
use time::OffsetDateTime;
|
2021-12-02 23:03:26 +08:00
|
|
|
use uuid::Uuid;
|
|
|
|
|
|
|
|
use super::batch::BatchId;
|
|
|
|
use crate::{
|
|
|
|
index::{Settings, Unchecked},
|
2022-05-19 18:43:46 +08:00
|
|
|
index_resolver::IndexUid,
|
2021-12-02 23:03:26 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
pub type TaskId = u64;
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
|
|
|
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
|
|
|
|
pub enum TaskResult {
|
|
|
|
DocumentAddition { indexed_documents: u64 },
|
|
|
|
DocumentDeletion { deleted_documents: u64 },
|
|
|
|
ClearAll { deleted_documents: u64 },
|
|
|
|
Other,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<DocumentAdditionResult> for TaskResult {
|
|
|
|
fn from(other: DocumentAdditionResult) -> Self {
|
|
|
|
Self::DocumentAddition {
|
|
|
|
indexed_documents: other.indexed_documents,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
|
|
|
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
|
|
|
|
pub enum TaskEvent {
|
2022-03-02 02:02:32 +08:00
|
|
|
Created(
|
|
|
|
#[cfg_attr(test, proptest(strategy = "test::datetime_strategy()"))]
|
|
|
|
#[serde(with = "time::serde::rfc3339")]
|
|
|
|
OffsetDateTime,
|
|
|
|
),
|
2021-12-02 23:03:26 +08:00
|
|
|
Batched {
|
|
|
|
#[cfg_attr(test, proptest(strategy = "test::datetime_strategy()"))]
|
2022-03-02 02:02:32 +08:00
|
|
|
#[serde(with = "time::serde::rfc3339")]
|
2022-02-14 22:32:41 +08:00
|
|
|
timestamp: OffsetDateTime,
|
2021-12-02 23:03:26 +08:00
|
|
|
batch_id: BatchId,
|
|
|
|
},
|
2022-03-02 02:02:32 +08:00
|
|
|
Processing(
|
|
|
|
#[cfg_attr(test, proptest(strategy = "test::datetime_strategy()"))]
|
|
|
|
#[serde(with = "time::serde::rfc3339")]
|
|
|
|
OffsetDateTime,
|
|
|
|
),
|
2021-12-02 23:03:26 +08:00
|
|
|
Succeded {
|
|
|
|
result: TaskResult,
|
|
|
|
#[cfg_attr(test, proptest(strategy = "test::datetime_strategy()"))]
|
2022-03-02 02:02:32 +08:00
|
|
|
#[serde(with = "time::serde::rfc3339")]
|
2022-02-14 22:32:41 +08:00
|
|
|
timestamp: OffsetDateTime,
|
2021-12-02 23:03:26 +08:00
|
|
|
},
|
|
|
|
Failed {
|
|
|
|
error: ResponseError,
|
|
|
|
#[cfg_attr(test, proptest(strategy = "test::datetime_strategy()"))]
|
2022-03-02 02:02:32 +08:00
|
|
|
#[serde(with = "time::serde::rfc3339")]
|
2022-02-14 22:32:41 +08:00
|
|
|
timestamp: OffsetDateTime,
|
2021-12-02 23:03:26 +08:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2022-01-27 00:43:16 +08:00
|
|
|
/// A task represents an operation that Meilisearch must do.
|
2021-12-02 23:03:26 +08:00
|
|
|
/// It's stored on disk and executed from the lowest to highest Task id.
|
|
|
|
/// Everytime a new task is created it has a higher Task id than the previous one.
|
|
|
|
/// See also `Job`.
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
|
|
|
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
|
|
|
|
pub struct Task {
|
|
|
|
pub id: TaskId,
|
2022-05-17 01:50:45 +08:00
|
|
|
/// 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.
|
2022-05-17 02:16:23 +08:00
|
|
|
#[cfg_attr(
|
|
|
|
test,
|
|
|
|
proptest(
|
|
|
|
strategy = "proptest::option::weighted(proptest::option::Probability::new(0.99), IndexUid::arbitrary())"
|
|
|
|
)
|
|
|
|
)]
|
2022-05-17 01:50:45 +08:00
|
|
|
pub index_uid: Option<IndexUid>,
|
2021-12-02 23:03:26 +08:00
|
|
|
pub content: TaskContent,
|
|
|
|
pub events: Vec<TaskEvent>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Task {
|
|
|
|
/// Return true when a task is finished.
|
|
|
|
/// A task is finished when its last state is either `Succeeded` or `Failed`.
|
|
|
|
pub fn is_finished(&self) -> bool {
|
|
|
|
self.events.last().map_or(false, |event| {
|
|
|
|
matches!(event, TaskEvent::Succeded { .. } | TaskEvent::Failed { .. })
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Return the content_uuid of the `Task` if there is one.
|
|
|
|
pub fn get_content_uuid(&self) -> Option<Uuid> {
|
|
|
|
match self {
|
|
|
|
Task {
|
|
|
|
content: TaskContent::DocumentAddition { content_uuid, .. },
|
|
|
|
..
|
|
|
|
} => Some(*content_uuid),
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
|
|
|
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
|
|
|
|
pub enum DocumentDeletion {
|
|
|
|
Clear,
|
|
|
|
Ids(Vec<String>),
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
|
|
|
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
|
|
|
|
#[allow(clippy::large_enum_variant)]
|
|
|
|
pub enum TaskContent {
|
|
|
|
DocumentAddition {
|
|
|
|
#[cfg_attr(test, proptest(value = "Uuid::new_v4()"))]
|
|
|
|
content_uuid: Uuid,
|
|
|
|
#[cfg_attr(test, proptest(strategy = "test::index_document_method_strategy()"))]
|
|
|
|
merge_strategy: IndexDocumentsMethod,
|
|
|
|
primary_key: Option<String>,
|
|
|
|
documents_count: usize,
|
2021-12-15 21:52:33 +08:00
|
|
|
allow_index_creation: bool,
|
2021-12-02 23:03:26 +08:00
|
|
|
},
|
|
|
|
DocumentDeletion(DocumentDeletion),
|
|
|
|
SettingsUpdate {
|
|
|
|
settings: Settings<Unchecked>,
|
|
|
|
/// Indicates whether the task was a deletion
|
|
|
|
is_deletion: bool,
|
2021-12-15 21:52:33 +08:00
|
|
|
allow_index_creation: bool,
|
2021-12-02 23:03:26 +08:00
|
|
|
},
|
|
|
|
IndexDeletion,
|
|
|
|
IndexCreation {
|
|
|
|
primary_key: Option<String>,
|
|
|
|
},
|
|
|
|
IndexUpdate {
|
|
|
|
primary_key: Option<String>,
|
|
|
|
},
|
2022-05-17 02:16:23 +08:00
|
|
|
Dump {
|
|
|
|
#[cfg_attr(test, proptest(value = "PathBuf::from(\".\")"))]
|
|
|
|
path: PathBuf,
|
|
|
|
},
|
2021-12-02 23:03:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod test {
|
|
|
|
use proptest::prelude::*;
|
|
|
|
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
pub(super) fn index_document_method_strategy() -> impl Strategy<Value = IndexDocumentsMethod> {
|
|
|
|
prop_oneof![
|
|
|
|
Just(IndexDocumentsMethod::ReplaceDocuments),
|
|
|
|
Just(IndexDocumentsMethod::UpdateDocuments),
|
|
|
|
]
|
|
|
|
}
|
|
|
|
|
2022-02-14 22:32:41 +08:00
|
|
|
pub(super) fn datetime_strategy() -> impl Strategy<Value = OffsetDateTime> {
|
|
|
|
Just(OffsetDateTime::now_utc())
|
2021-12-02 23:03:26 +08:00
|
|
|
}
|
|
|
|
}
|