An open API service indexing awesome lists of open source software.

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.

Awesome Lists containing this project

README

          

# Bonsaimq

[![crates.io page](https://img.shields.io/crates/v/bonsaimq.svg)](https://crates.io/crates/bonsaimq)
[![docs.rs page](https://docs.rs/bonsaimq/badge.svg)](https://docs.rs/bonsaimq/)
![license: MIT](https://img.shields.io/crates/l/bonsaimq.svg)

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.