feat: add 4 new crates (queue, tracing, http, cli) + enhancements to existing crates

New crates:
- mytheclipse-queue: unified job queue with WorkerPool, retry/backoff, DLQ
  Backends: in-memory (default), Redis, NATS, PostgreSQL
- mytheclipse-tracing: tracing subscriber layers with env filter + OTLP/Jaeger export
- mytheclipse-http: HTTP client/server with timeout + tracing, axum server
- mytheclipse-cli: CLI framework with clap derive, built-in subcommands

Enhancements to existing crates:
- mytheclipse-core: SemaphorePool, LeaderElection, HealthRegistry/HealthCheck
- mytheclipse-cache: AutoRefreshCache (bg refresh on miss), CacheMetrics
- mytheclipse-config: ConfigSchema for JSON Schema generation
- mytheclipse-storage: MultipartUploadDriver trait
- mytheclipse-crypto: PASETO v4.local token support

All features compile with --all-features; tests + clippy pass clean.
This commit is contained in:
asepharyana
2026-08-29 16:05:02 +07:00
parent 2596b357ec
commit 8106f8943e
53 changed files with 3588 additions and 44 deletions
+50
View File
@@ -0,0 +1,50 @@
//! The core `Queue` trait and supporting types.
use async_trait::async_trait;
use std::time::Duration;
use crate::job::Job;
use crate::error::{QueueError, JobError};
/// A handle to a single unit of queued work.
///
/// `Job` carries the raw payload (arbitrary bytes — caller decides encoding)
/// plus metadata the queue implementation fills in (ID, enqueue time, retry
/// count). `ack`/`nack` are only valid on backends that support explicit
/// acknowledgment (NATS, Redis BLPOP-with-confirm). For in-memory and Postgres
/// backends, the worker auto-acknowledges on `Ok` and auto-requeues on `Err`.
/// A trait for enqueueing and dequeueing jobs.
///
/// Implementations must be `Send + Sync`. Each backend provides its own factory
/// (e.g. `InMemoryQueue::new()`, `RedisQueue::connect(url)`).
#[async_trait]
pub trait Queue: Send + Sync {
/// Enqueues `payload` onto `topic`.
async fn enqueue(&self, topic: &str, payload: Vec<u8>) -> Result<(), QueueError>;
/// Dequeues the next job from `topic`, waiting up to `timeout`.
///
/// Returns `None` on timeout when the queue is empty and no job arrives
/// within the window.
async fn dequeue(&self, topic: &str, timeout: Duration) -> Result<Option<Job>, QueueError>;
/// Acknowledges a job as successfully processed.
async fn ack(&self, job: &Job) -> Result<(), JobError>;
/// Negative-acknowledges a job. If `requeue` is true the job goes back
/// onto the queue; if false it moves to the dead-letter queue (if
/// configured).
async fn nack(&self, job: &Job, requeue: bool) -> Result<(), JobError>;
/// Moves a job to the dead-letter queue for `topic`.
async fn dlq_move(&self, topic: &str, job: Job) -> Result<(), QueueError>;
/// Number of messages currently waiting in `topic`.
async fn len(&self, topic: &str) -> Result<u64, QueueError>;
/// Whether the queue is empty.
async fn is_empty(&self, topic: &str) -> Result<bool, QueueError> {
Ok(self.len(topic).await? == 0)
}
}