reinhardt_tasks/lib.rs
1//! # Reinhardt Background Tasks
2//!
3//! Celery-inspired background task queue for Reinhardt framework.
4//!
5//! ## Features
6//!
7//! - Async task execution
8//! - Task scheduling (cron-like)
9//! - Task retries with exponential backoff
10//! - Task priority
11//! - Task chaining
12//! - Task dependencies and DAG execution
13//! - Result backend
14//! - Task execution metrics and monitoring
15//! - Worker load balancing (Round-robin, Least-connections, Weighted, Random)
16//! - Webhook notifications for task completion
17//!
18//!
19//! ## Example
20//!
21//! ```rust,no_run
22//! # use reinhardt_tasks::TaskResult;
23//! # trait Task {}
24//! # #[derive(Clone)]
25//! # struct SendEmailTask { to: String, subject: String, body: String }
26//! # trait TaskQueue {
27//! # fn new() -> Self;
28//! # async fn enqueue(&self, task: SendEmailTask) -> TaskResult<()>;
29//! # }
30//! # struct QueueImpl;
31//! # impl TaskQueue for QueueImpl {
32//! # fn new() -> Self { QueueImpl }
33//! # async fn enqueue(&self, task: SendEmailTask) -> TaskResult<()> { Ok(()) }
34//! # }
35//! #
36//! # #[tokio::main]
37//! # async fn main() -> TaskResult<()> {
38//! // Example: Define a task
39//! // struct SendEmailTask {
40//! // to: String,
41//! // subject: String,
42//! // body: String,
43//! // }
44//!
45//! // #[async_trait]
46//! // impl TaskExecutor for SendEmailTask {
47//! // async fn execute(&self) -> TaskResult<()> {
48//! // Send email
49//! // Ok(())
50//! // }
51//! // }
52//!
53//! // Queue the task
54//! let queue = QueueImpl::new();
55//! queue.enqueue(SendEmailTask {
56//! to: "user@example.com".to_string(),
57//! subject: "Hello".to_string(),
58//! body: "Test email".to_string(),
59//! }).await?;
60//! # Ok(())
61//! # }
62//! ```
63
64#![warn(missing_docs)]
65
66/// Task backend trait and built-in implementations.
67pub mod backend;
68/// Feature-gated backend implementations (Redis, SQLite, SQS, RabbitMQ).
69pub mod backends;
70/// Task chaining for sequential execution pipelines.
71pub mod chain;
72/// Directed acyclic graph (DAG) based task dependencies.
73pub mod dag;
74/// Worker load balancing strategies.
75pub mod load_balancer;
76/// Distributed task locking to prevent duplicate execution.
77pub mod locking;
78/// Task execution metrics and monitoring.
79pub mod metrics;
80/// Priority-based task queue.
81pub mod priority_queue;
82/// Core task queue with configuration.
83pub mod queue;
84/// Task registry for serialization and discovery.
85pub mod registry;
86/// Result backend for storing task outputs.
87pub mod result;
88/// Retry policies with exponential backoff.
89pub mod retry;
90/// Cron-like task scheduling.
91pub mod scheduler;
92/// Task trait and execution lifecycle.
93pub mod task;
94/// Webhook notifications for task completion events.
95pub mod webhook;
96/// Task worker execution loop.
97pub mod worker;
98
99pub use backend::{
100 DummyBackend, ImmediateBackend, ResultStatus, TaskBackend, TaskBackends, TaskExecutionError,
101 TaskResultStatus,
102};
103
104#[cfg(feature = "redis-backend")]
105pub use backends::RedisTaskBackend;
106
107#[cfg(feature = "database-backend")]
108pub use backends::SqliteBackend;
109
110#[cfg(feature = "sqs-backend")]
111pub use backends::{SqsBackend, SqsConfig};
112
113#[cfg(feature = "rabbitmq-backend")]
114pub use backends::{RabbitMQBackend, RabbitMQConfig};
115pub use chain::{ChainStatus, TaskChain, TaskChainBuilder};
116pub use dag::{TaskDAG, TaskNode, TaskNodeStatus};
117pub use load_balancer::{LoadBalancer, LoadBalancingStrategy, WorkerId, WorkerInfo, WorkerMetrics};
118pub use locking::{LockToken, MemoryTaskLock, TaskLock};
119
120#[cfg(feature = "redis-backend")]
121pub use locking::RedisTaskLock;
122pub use metrics::{MetricsSnapshot, TaskCounts, TaskMetrics, WorkerStats};
123pub use priority_queue::{Priority, PriorityTaskQueue};
124pub use queue::{QueueConfig, TaskQueue};
125pub use registry::{SerializedTask, TaskFactory, TaskRegistry};
126pub use result::{
127 MemoryResultBackend, ResultBackend, TaskOutput, TaskResult as TaskResultBackend,
128 TaskResultMetadata,
129};
130
131#[cfg(feature = "redis-backend")]
132pub use backends::redis::RedisTaskResultBackend;
133
134#[cfg(feature = "database-backend")]
135pub use backends::sqlite::SqliteResultBackend;
136
137#[cfg(feature = "sqs-backend")]
138pub use backends::sqs::SqsResultBackend;
139pub use retry::{RetryState, RetryStrategy};
140pub use scheduler::{CronSchedule, Schedule, Scheduler};
141pub use task::{
142 DEFAULT_TASK_QUEUE_NAME, TASK_MAX_PRIORITY, TASK_MIN_PRIORITY, Task, TaskExecutor, TaskId,
143 TaskPriority, TaskStatus,
144};
145pub use webhook::{
146 HttpWebhookSender, RetryConfig, TaskStatus as WebhookTaskStatus, WebhookConfig, WebhookError,
147 WebhookEvent, WebhookSender, is_blocked_ip, validate_resolved_ips, validate_webhook_url,
148};
149pub use worker::{Worker, WorkerConfig};
150
151use thiserror::Error;
152
153/// Result type for task operations
154pub type TaskResult<T> = Result<T, TaskError>;
155
156/// Task-related errors
157///
158/// # Example
159///
160/// ```rust
161/// use reinhardt_tasks::TaskError;
162///
163/// let error = TaskError::ExecutionFailed("Database connection failed".to_string());
164/// assert_eq!(error.to_string(), "Task execution failed: Database connection failed");
165/// ```
166#[derive(Debug, Error)]
167pub enum TaskError {
168 /// Task execution failed
169 ///
170 /// # Example
171 ///
172 /// ```rust
173 /// use reinhardt_tasks::TaskError;
174 ///
175 /// let error = TaskError::ExecutionFailed("Network error".to_string());
176 /// ```
177 #[error("Task execution failed: {0}")]
178 ExecutionFailed(String),
179
180 /// Task not found
181 ///
182 /// # Example
183 ///
184 /// ```rust
185 /// use reinhardt_tasks::TaskError;
186 ///
187 /// let error = TaskError::TaskNotFound("task-123".to_string());
188 /// assert_eq!(error.to_string(), "Task not found: task-123");
189 /// ```
190 #[error("Task not found: {0}")]
191 TaskNotFound(String),
192
193 /// Queue error
194 #[error("Queue error: {0}")]
195 QueueError(String),
196
197 /// Serialization error
198 #[error("Serialization error: {0}")]
199 SerializationError(String),
200
201 /// Task timeout
202 ///
203 /// # Example
204 ///
205 /// ```rust
206 /// use reinhardt_tasks::TaskError;
207 ///
208 /// let error = TaskError::Timeout;
209 /// assert_eq!(error.to_string(), "Task timeout");
210 /// ```
211 #[error("Task timeout")]
212 Timeout,
213
214 /// Max retries exceeded
215 ///
216 /// # Example
217 ///
218 /// ```rust
219 /// use reinhardt_tasks::TaskError;
220 ///
221 /// let error = TaskError::MaxRetriesExceeded;
222 /// assert_eq!(error.to_string(), "Max retries exceeded");
223 /// ```
224 #[error("Max retries exceeded")]
225 MaxRetriesExceeded,
226}