From 9d5cc88cd5d99ec937478e7b0182bee7a8f398ef Mon Sep 17 00:00:00 2001 From: Kerollmops Date: Tue, 31 May 2022 11:56:51 +0200 Subject: [PATCH] Implement the seek-based tasks list pagination --- meilisearch-http/src/routes/tasks.rs | 33 +++++++++++++++++++++++----- meilisearch-http/src/task.rs | 12 ++++------ 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/meilisearch-http/src/routes/tasks.rs b/meilisearch-http/src/routes/tasks.rs index ca4824517..821142399 100644 --- a/meilisearch-http/src/routes/tasks.rs +++ b/meilisearch-http/src/routes/tasks.rs @@ -26,6 +26,8 @@ pub struct TaskFilterQuery { type_: Option>>, status: Option>>, index_uid: Option>>, + limit: Option, // TODO must not return an error when deser fail + after: Option, // TODO must not return an error when deser fail } #[rustfmt::skip] @@ -68,11 +70,13 @@ async fn get_tasks( type_, status, index_uid, + limit, + after, } = params.into_inner(); let search_rules = &meilisearch.filters().search_rules; - // We first tranform a potential indexUid=* into a "not specified indexUid filter" + // We first transform a potential indexUid=* into a "not specified indexUid filter" // for every one of the filters: type, status, and indexUid. let type_ = type_.map(CS::into_inner).and_then(fold_star_or); let status = status.map(CS::into_inner).and_then(fold_star_or); @@ -128,13 +132,32 @@ async fn get_tasks( indexes_filters }; - let tasks: TaskListView = meilisearch - .list_tasks(filters, None, None) + // We +1 just to know if there is more after this "page" or not. + let limit = limit.unwrap_or(DEFAULT_LIMIT).saturating_add(1); + // We -1 here because we need an offset and we must exclude the `after` one. + let offset = after.map(|n| n.saturating_sub(1)); + + let mut tasks_results = meilisearch + .list_tasks(filters, Some(limit), offset) .await? .into_iter() .map(TaskView::from) - .collect::>() - .into(); + .collect::>(); + + // If we were able to fetch the number +1 tasks we asked + // it means that there is more to come. + let after = if tasks_results.len() == limit { + tasks_results.pop(); + tasks_results.last().map(|t| t.uid) + } else { + None + }; + + let tasks = TaskListView { + results: tasks_results, + limit: limit.saturating_sub(1), + after, + }; Ok(HttpResponse::Ok().json(tasks)) } diff --git a/meilisearch-http/src/task.rs b/meilisearch-http/src/task.rs index 56eeabfc8..8eec71a4e 100644 --- a/meilisearch-http/src/task.rs +++ b/meilisearch-http/src/task.rs @@ -180,7 +180,7 @@ fn serialize_duration( #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct TaskView { - uid: TaskId, + pub uid: TaskId, index_uid: Option, status: TaskStatus, #[serde(rename = "type")] @@ -369,13 +369,9 @@ impl From for TaskView { #[derive(Debug, Serialize)] pub struct TaskListView { - results: Vec, -} - -impl From> for TaskListView { - fn from(results: Vec) -> Self { - Self { results } - } + pub results: Vec, + pub limit: usize, + pub after: Option, } #[derive(Debug, Serialize)]