QuickDID is a high-performance AT Protocol identity resolution service written in Rust. It provides handle-to-DID resolution with Redis-backed caching and queue processing.
at main 2.5 kB view raw
1//! Task management utilities for consistent background task handling 2//! 3//! This module provides helpers for spawning and managing background tasks with: 4//! - Consistent start/stop logging 5//! - Automatic shutdown on task failure 6//! - Graceful shutdown support 7 8use std::future::Future; 9use tokio_util::{sync::CancellationToken, task::TaskTracker}; 10use tracing::{error, info}; 11 12/// Spawn a background task with cancellation support 13/// 14/// This version allows the task to be cancelled via the token and handles 15/// both graceful shutdown and unexpected failures 16pub fn spawn_cancellable_task<F, Fut>( 17 tracker: &TaskTracker, 18 app_token: CancellationToken, 19 task_name: &str, 20 task_builder: F, 21) where 22 F: FnOnce(CancellationToken) -> Fut + Send + 'static, 23 Fut: Future<Output = anyhow::Result<()>> + Send + 'static, 24{ 25 info!(task = task_name, "Starting cancellable background task"); 26 27 let task_token = app_token.clone(); 28 let cancel_token = app_token.clone(); 29 30 let inner_task_name = task_name.to_string(); 31 32 tracker.spawn(async move { 33 tokio::select! { 34 result = task_builder(cancel_token.clone()) => { 35 match result { 36 Ok(()) => { 37 info!(task = inner_task_name, "Background task completed successfully"); 38 } 39 Err(e) => { 40 error!(error = ?e, task = inner_task_name, "Background task failed unexpectedly"); 41 // Trigger application shutdown on task failure 42 task_token.cancel(); 43 } 44 } 45 } 46 () = task_token.cancelled() => { 47 info!(task = inner_task_name, "Background task shutting down gracefully"); 48 } 49 } 50 }); 51} 52 53/// Macro for consistent task error handling within a task 54#[macro_export] 55macro_rules! task_try { 56 ($expr:expr, $task_name:expr) => { 57 match $expr { 58 Ok(val) => val, 59 Err(e) => { 60 tracing::error!(task = $task_name, error = ?e, "Task operation failed"); 61 return Err(e.into()); 62 } 63 } 64 }; 65} 66 67/// Macro for logging task checkpoints 68#[macro_export] 69macro_rules! task_checkpoint { 70 ($task_name:expr, $checkpoint:expr) => { 71 tracing::debug!( 72 task = $task_name, 73 checkpoint = $checkpoint, 74 "Task checkpoint reached" 75 ); 76 }; 77}