Simple and flexible queue implementation for Rust with support for multiple backends (Redis, RabbitMQ, SQS, etc.)

Overview

Omniqueue

Omniqueue is an abstraction layer over queue backends for Rust. It includes support for RabbitMQ, Redis streams, and SQS out of the box. The trait may also be implemented for other backends to meet your own needs.

Omniqueue provides a high level interface which allows sending and receiving raw byte arrays, any serde Deserailize and Serialize implementors via JSON encoded byte arrays, or any arbitrary types for which you have provided an encoding and/or decoding function.

It is designed to be flexible and to be able to adapt to fit your existing queue configurations, but with a set of defaults that makes it simple to start seding and reciving quickly.

Omniqueue is still early in development.

How to use Omniqueue

While the exact configuration will depend on the backend used, usage is roughly as follows.

  1. Add omniqueue to your Cargo.toml. All backends are enabled by default including RabbitMQ, Redis (via their stream type), SQS, and an in-memory queue based off ot tokio broadcast channel which is perfect for testing.

    If you only need some backends, then simply disable the default features, and enable any backends that you require.

  2. Construct anud use your queue.

    The exact configuration type used will depend on your backend, but it's as simple as:

    let cfg = SqsConfig {
        queue_dsn: "http://localhost:9324/queue/queue_name".to_owned(),
        override_endpoint: true,
    };
    let (producer, mut consumer) = SqsQueueBackend::builder(cfg).build_pair().await?;
    
    producer.send_serde_json(&ExampleType::default()).await?;
    
    let delivery = c.receive().await?;
    assert_eq!(
        delivery.payload_serde_json::<ExampleType>().await?,
        Some(ExampleType::default())
    );
    
    delivery.ack().await?;

    The producer and consumers returned implement the QueueProducer and QueueConsumer traits respectively. This means you can make functions generic over any queue backend. Alternatively, if you need dynamic dispatch, it's as simple as one extra line ih the builder:

    let cfg = SqsConfig {
        queue_dsn: "http://localhost:9324/queue/queue_name".to_owned(),
        override_endpoint: true,
    };
    let (producer, mut consumer) = SqsQueueBackend::builder(cfg)
        .make_dynamic()
        .build_pair()
        .await?;

Encoders and Decoders

Part of the design of this crate was a clear separation of responsibility. The users of the queue generically should never have to concern themselves with how any given item is represented within the queue backend. Instead, they should be allowed to think only in Rust types.

On the other hand, the users who define which backend to use should be the only ones concerned with getting the queue's internal representations to the Rust types.

Enter CustomEncoders and CustomDecoders: these are a simple as closures or function pointers that convert from regular Rust types to the type expected by the queue backend's input or output.

They are defined and used as follows:

#[derive(Debug, PartialEq)]
struct ExampleType {
	field: u8,
}


let (p, mut c) = RabbitMqBackend::builder(cfg)
	// RabbitMQ's internal representation is an arbitrary byte array.
	.with_encoder(|et: &ExampleType| -> Result<Vec<u8>, QueueError> {
		Ok(vec![et.field])
	})
	.with_decoder(|v: &Vec<u8>| -> Result<ExampleType, QueueError> {
		Ok(ExampleType {
			field: *v.first().unwrap_or(i&0),
		})
	})
	.build_pair()
	.await?;

let payload = ExampleType { field: 2 };

p.send_custom(&payload).await?;

let delivery = c.receive().await?;
assert_eq!(d.payload_custom::<ExampleType>()?, Some(payload))

delivery.ack().await?;

These functions are called automatically assuming you have an encoder and/or decoder for the right type. This makes adapting the crate to an existing queue whose internal data layout doesn't match the defaults to a T as simple as possible.

You might also like...
A rust Key-Value store based on Redis.

Key-Value Store A Key-Value store that uses Redis to store data. Built using an async web framework in Rust with a full Command-Line interface and log

Basic Redis Protocol specification in Rust

Basic Redis Protocol specification in Rust

Redis compatible server framework for Rust
Redis compatible server framework for Rust

Redis compatible server framework for Rust Features Create a fast custom Redis compatible server in Rust Simple API. Support for pipelining and telnet

📺 Netflix in Rust/ React-TS/ NextJS, Actix-Web, Async Apollo-GraphQl, Cassandra/ ScyllaDB, Async SQLx, Kafka, Redis, Tokio, Actix, Elasticsearch, Influxdb Iox, Tensorflow, AWS
📺 Netflix in Rust/ React-TS/ NextJS, Actix-Web, Async Apollo-GraphQl, Cassandra/ ScyllaDB, Async SQLx, Kafka, Redis, Tokio, Actix, Elasticsearch, Influxdb Iox, Tensorflow, AWS

Fullstack Movie Streaming Platform 📺 Netflix in RUST/ NextJS, Actix-Web, Async Apollo-GraphQl, Cassandra/ ScyllaDB, Async SQLx, Spark, Kafka, Redis,

Learning Rust by implementing parts of redis.

Redis This is a simple CLI Redis inspired project that supports the GET, SET, and INCR commands. Run it Have rust installed (if you don't, visit rustu

RedisJSON - a JSON data type for Redis

RedisJSON RedisJSON is a Redis module that implements ECMA-404 The JSON Data Interchange Standard as a native data type. It allows storing, updating a

[POC] Redis Module for TiKV

RedisTikvPoc [POC] Redis Module for TiKV This is a POC repository. This Redis Module will add branch new Redis commands to operate TiKV data. After bu

A port of `java.util.*SummaryStatistics` as a Redis Module

RedisNumbersStats RedisNumbersStats is a Redis module that implements a Redis version of the Java Util *SummaryStatistics classes, such as DoubleSumma

A simplified version of a Redis server supporting SET/GET commands

This is a starting point for Rust solutions to the "Build Your Own Redis" Challenge. In this challenge, you'll build a toy Redis clone that's capable

Releases(v0.1.0)
Owner
Svix
Webhooks as a service
Svix
Sharded, concurrent mini redis that support http interface implemented in rust

Rudis A mini version of redis server that provides http interface implemented in Rust. The in-memorry kv-storage is sharded and concurrent safe. Inspi

Lorenzo Cao 43 May 30, 2023
Incomplete Redis client and server implementation using Tokio - for learning purposes only

mini-redis mini-redis is an incomplete, idiomatic implementation of a Redis client and server built with Tokio. The intent of this project is to provi

Tokio 2.3k Jan 4, 2023
An intentionally-limited Rust implementation of the Redis server with no external dependencies.

lil-redis An intentionally-limited Rust implementation of the Redis server. lil redis is an accessible implementation of a very basic Redis server (wi

Miguel Piedrafita 37 Jan 1, 2023
Rewrite Redis in Rust for evaluation and learning.

Drill-Redis This library has been created for the purpose of evaluating Rust functionality and performance. As such, it has not been fully tested. The

Akira Kawahara 3 Oct 18, 2022
Lightweight async Redis client with connection pooling written in pure Rust and 100% memory safe

redi-rs (or redirs) redi-rs is a Lightweight Redis client with connection pooling written in Rust and 100% memory safe redi-rs is a Redis client writt

Oğuz Türkay 4 May 20, 2023
RedisLess is a fast, lightweight, embedded and scalable in-memory Key/Value store library compatible with the Redis API.

RedisLess is a fast, lightweight, embedded and scalable in-memory Key/Value store library compatible with the Redis API.

Qovery 145 Nov 23, 2022
Macros for redis-rs to serialize and deserialize structs automatically

redis-macros Simple macros and wrappers to redis-rs to automatically serialize and deserialize structs with serde. Installation To install it, simply

Daniel Grant 4 Feb 18, 2023
SQLite Extension adding various hashing functions like MD5, SHA1, SHA256, SHA512, etc.

sqlite-hashes Use this crate to add various hash functions to SQLite, including MD5, SHA1, SHA256, and SHA512. This crate uses rusqlite to add user-de

Yuri Astrakhan 3 Jul 28, 2023
Redis re-implemented in Rust.

rsedis Redis re-implemented in Rust. Why? To learn Rust. Use Cases rsedis does not rely on UNIX-specific features. Windows users can run it as a repla

Sebastian Waisbrot 1.6k Jan 6, 2023
Redis library for rust

redis-rs Redis-rs is a high level redis library for Rust. It provides convenient access to all Redis functionality through a very flexible but low-lev

Armin Ronacher 2.8k Jan 8, 2023