Skip to main content

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}