https://github.com/flixcoder/bonsaimq
Message/job queue based on bonsaidb, similar to sqlxmq.
https://github.com/flixcoder/bonsaimq
database message persistent queue rust
Last synced: 6 months ago
JSON representation
Message/job queue based on bonsaidb, similar to sqlxmq.
- Host: GitHub
- URL: https://github.com/flixcoder/bonsaimq
- Owner: FlixCoder
- License: mit
- Archived: true
- Created: 2022-05-26T08:52:30.000Z (almost 4 years ago)
- Default Branch: main
- Last Pushed: 2025-04-06T14:59:28.000Z (12 months ago)
- Last Synced: 2025-10-04T02:57:19.661Z (6 months ago)
- Topics: database, message, persistent, queue, rust
- Language: Rust
- Homepage: https://crates.io/crates/bonsaimq
- Size: 73.2 KB
- Stars: 7
- Watchers: 4
- Forks: 0
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Funding: .github/FUNDING.yml
- License: LICENSE.md
Awesome Lists containing this project
README
# Bonsaimq
[](https://crates.io/crates/bonsaimq)
[](https://docs.rs/bonsaimq/)

Simple database message queue based on [bonsaidb](https://github.com/khonsulabs/bonsaidb).
The project is highly influenced by [sqlxmq](https://github.com/Diggsey/sqlxmq).
Warning: This project is in early alpha and should not be used in production!
## Usage
Import the project using:
```bash
cargo add bonsaimq
```
or
```toml
# adjust the version to the latest version:
bonsaimq = "0.3.0"
# or
bonsaimq = { git = "https://github.com/FlixCoder/bonsaimq" }
```
Then you can use the message/job queue as follows:
- You need job handlers, which are async functions that receive one argument of type `CurrentJob` and return nothing. `CurrentJob` allows interfacing the job to retrieve job input or complete the job etc.
- The macro `job_regristy!` needs to be use to create a job registry, which maps message names/types to the job handlers and allows spawning new jobs.
- A job runner needs to be created and run on a bonsai database. It runs in the background as long as the handle is in scope and executes the jobs according to the incoming messages. It acts on the job registry.
## Example
Besides the following simple example, see the examples in the [examples folder](https://github.com/FlixCoder/bonsaimq/tree/main/examples/) and take a look at the tests.
```rust
use bonsaidb::local::{
config::{Builder, StorageConfiguration},
AsyncDatabase,
};
use bonsaimq::{job_registry, CurrentJob, JobRegister, JobRunner, MessageQueueSchema};
use color_eyre::Result;
/// Example job function. It receives a handle to the current job, which gives
/// the ability to get the input payload, complete the job and more.
async fn greet(mut job: CurrentJob) -> color_eyre::Result<()> {
// Load the JSON payload and make sure it is there.
let name: String = job.payload_json().expect("input should be given")?;
println!("Hello {name}!");
job.complete().await?;
Ok(())
}
// The JobRegistry provides a way to spawn new jobs and provides the interface
// for the JobRunner to find the functions to execute for the jobs.
job_registry!(JobRegistry, {
Greetings: "greet" => greet,
});
#[tokio::main]
async fn main() -> Result<()> {
// Open a local database for this example.
let db_path = "simple-doc-example.bonsaidb";
let db = AsyncDatabase::open::(StorageConfiguration::new(db_path)).await?;
// Start the job runner to execute jobs from the messages in the queue in the
// database.
let job_runner = JobRunner::new(db.clone()).run::();
// Spawn new jobs via a message on the database queue.
let job_id = JobRegistry::Greetings.builder().payload_json("cats")?.spawn(&db).await?;
// Wait for job to finish execution, polling every 100 ms.
bonsaimq::await_job(job_id, 100, &db).await?;
// Clean up.
job_runner.abort(); // Is done automatically on drop.
tokio::fs::remove_dir_all(db_path).await?;
Ok(())
}
```
## Minimum supported Rust version
Currently, I am always using the latest Rust version and do not put in any effort to keep the MSRV. Please open an issue in case you need a different policy, I might consider changing the policy.
## License
Licensed under the MIT license. All contributors agree to license under this license.