docbox_core/tasks/
background_task.rs1use chrono::{DateTime, Utc};
2use docbox_database::{
3 DbPool, DbResult,
4 models::{
5 document_box::DocumentBoxScopeRaw,
6 tasks::{Task, TaskId, TaskStatus},
7 },
8};
9use std::{future::Future, time::Duration};
10use tokio::time::sleep;
11use tracing::Instrument;
12
13pub async fn background_task<Fut>(
14 db: DbPool,
15 scope: DocumentBoxScopeRaw,
16 future: Fut,
17) -> DbResult<(TaskId, DateTime<Utc>)>
18where
19 Fut: Future<Output = (TaskStatus, serde_json::Value)> + Send + 'static,
20{
21 let mut task = Task::create(&db, scope).await?;
23
24 let task_id = task.id;
25 let created_at = task.created_at;
26
27 let span = tracing::Span::current();
28
29 tokio::spawn(
31 async move {
32 let (status, output) = future.await;
33
34 for i in 1..5 {
39 match task.complete_task(&db, status, Some(output.clone())).await {
41 Ok(_) => break,
42 Err(error) => {
43 tracing::error!(?error, "failed to mark task as complete");
44 sleep(Duration::from_secs(60 * (i * i))).await;
45 }
46 }
47 }
48 }
49 .instrument(span),
50 );
51
52 Ok((task_id, created_at))
53}