From a27d278014f46f01949f40dc86c7b65033c1fe0c Mon Sep 17 00:00:00 2001 From: kjuulh Date: Tue, 22 Jul 2025 22:05:51 +0200 Subject: [PATCH] docs: add readme --- README.md | 107 +++++++++++++++++++++++++++++++++++++++ crates/nodrop/src/lib.rs | 6 ++- 2 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..88ae6a8 --- /dev/null +++ b/README.md @@ -0,0 +1,107 @@ +# ๐ŸงŠ nodrop + +**`nodrop`** is a simple, composable async drop queue for Rust โ€” built to run queued tasks in FIFO order and ensure graceful shutdown via draining. It's useful in lifecycle-managed environments (e.g., `notmad`) or as a lightweight alternative until async drop is stabilized in Rust. + +> ๐Ÿ’ก Tasks are executed one at a time. If the queue is marked for draining, no further items can be added. + +--- + +## โœจ Features + +* Assign one-off async tasks (closures) to a queue +* FIFO task processing +* Draining mechanism to flush the queue before shutdown +* Optional integration with [`notmad`](https://crates.io/crates/notmad) for graceful component lifecycle control +* `Send + Sync + 'static` guaranteed + +--- + +## ๐Ÿš€ Usage + +### Add to `Cargo.toml` + +```toml +[dependencies] +nodrop = { git = "https://github.com/kjuulh/nodrop" } +``` + +### Enable `notmad` integration (optional) + +```toml +[dependencies] +nodrop = { git = "https://github.com/kjuulh/nodrop", features = ["notmad"] } +``` + +--- + +## ๐Ÿ›  Example + +```rust +use nodrop::DropQueue; +use tokio::sync::oneshot; + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + let queue = DropQueue::new(); + + let (tx, rx) = oneshot::channel(); + + queue.assign(|| async move { + println!("Running closure task"); + tx.send(()).unwrap(); + Ok(()) + })?; + + queue.process_next().await?; + + rx.await?; + + Ok(()) +} +``` + +--- + +## ๐Ÿ” Lifecycle with `notmad` + +If using the [`notmad`](https://crates.io/crates/notmad) lifecycle framework: + +```rust +#[tokio::main] +async fn main() -> anyhow::Result<()> { + let queue = nodrop::DropQueue::new(); + let app = notmad::Mad::new().add(queue); + app.run().await?; + Ok(()) +} +``` + +This will process tasks until the cancellation token is triggered, e.g., via SIGINT. + +--- + +## ๐Ÿ”’ Drain Mode + +You can signal the queue to stop accepting new items and finish processing the current ones: + +```rust +queue.drain().await?; +``` + +After this call, any further `assign()` will panic. + +--- + +## ๐Ÿงช Tests + +Run the test suite using: + +```bash +cargo test +``` + +--- + +## ๐Ÿ“œ License + +MIT diff --git a/crates/nodrop/src/lib.rs b/crates/nodrop/src/lib.rs index 7790a63..eaa006a 100644 --- a/crates/nodrop/src/lib.rs +++ b/crates/nodrop/src/lib.rs @@ -107,13 +107,17 @@ impl DropQueue { loop { tokio::select! { _ = cancellation_token.cancelled() => { - return Ok(()) + break; }, res = self.process_next() => { res?; } } } + + self.drain().await?; + + Ok(()) } }