This commit is contained in:
107
README.md
Normal file
107
README.md
Normal file
@@ -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
|
@@ -107,13 +107,17 @@ impl DropQueue {
|
|||||||
loop {
|
loop {
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
_ = cancellation_token.cancelled() => {
|
_ = cancellation_token.cancelled() => {
|
||||||
return Ok(())
|
break;
|
||||||
},
|
},
|
||||||
res = self.process_next() => {
|
res = self.process_next() => {
|
||||||
res?;
|
res?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.drain().await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user