turul_mcp_server/task/executor.rs
1//! Task Executor — abstraction for how task work is executed.
2//!
3//! Separates *how tasks run* from *how tasks are stored*.
4//! Default: `TokioTaskExecutor` (in-process async).
5//! Future: EventBridge, SQS, Step Functions worker models.
6
7use std::future::Future;
8use std::pin::Pin;
9
10use async_trait::async_trait;
11
12use turul_mcp_protocol::TaskStatus;
13use turul_mcp_task_storage::TaskStorageError;
14
15/// Opaque handle returned when a task is started.
16pub trait TaskHandle: Send + Sync {
17 /// Request cancellation of the running task.
18 fn cancel(&self);
19 /// Check if cancellation has been requested.
20 fn is_cancelled(&self) -> bool;
21}
22
23/// Boxed async work unit — the actual operation to execute.
24pub type BoxedTaskWork = Box<
25 dyn FnOnce() -> Pin<Box<dyn Future<Output = turul_mcp_task_storage::TaskOutcome> + Send>>
26 + Send,
27>;
28
29/// Trait for executing task work and managing runtime lifecycle.
30#[async_trait]
31pub trait TaskExecutor: Send + Sync {
32 /// Start executing a task. Returns an opaque handle for cancellation.
33 async fn start_task(
34 &self,
35 task_id: &str,
36 work: BoxedTaskWork,
37 ) -> Result<Box<dyn TaskHandle>, TaskStorageError>;
38
39 /// Cancel a running task by ID.
40 async fn cancel_task(&self, task_id: &str) -> Result<(), TaskStorageError>;
41
42 /// Block until a task reaches terminal status.
43 /// Returns the terminal status, or None if the task is not tracked by this executor.
44 async fn await_terminal(&self, task_id: &str) -> Option<TaskStatus>;
45}