[][src]Crate hive_pubsub

Hive is a generic Pub/Sub library for Rust.

By default, Hive provides a very basic pub/sub system which you can integrate into something like a web socket server, this system is perfect for small-scale applications which only use one node.

It is important to note that Hive is not for everyone, all the data is returned through one callback which is intended to be piped into things such as websocket servers, mpsc channels, etc. (If you want this functionality, feel free to contact me and I'll put it higher on my priority list)

Example

use hive_pubsub::{Hive, PubSub};
 
let mut hive = Hive::new(
    |users, data| {
        println!("Received data! [{:?}]: {}.", users, data);
    }
);
 
hive.subscribe_multiple(1, vec! [ 2, 5 ]).unwrap();
hive.subscribe_multiple(3, vec! [ 2, 6 ]).unwrap();
hive.subscribe_multiple(4, vec! [ 2, 5 ]).unwrap();
 
hive.drop_topic(&6).unwrap();
hive.publish(&6, "This will not appear.".to_string()).unwrap();
hive.publish(&2, "This will appear for all three clients.".to_string()).unwrap();
 
hive.drop_client(&3).unwrap();
hive.publish(&2, "This will appear for two of the clients.".to_string()).unwrap();
hive.publish(&5, "This will also appear for two of the clients.".to_string()).unwrap();

Example, for use with MongoDB.

This example is designed for the latest version of MongoDB and is async-runtime agnostic. Tokio is only required for the example below to run, as well as the tests in the library. You may use async-std or tokio.

Important: before listening on the collection, make sure to create a capped collection! My recommendation is that your application should have some sort of database migrations system in place which should automatically create this.

use std::env::var;
use mongodb::Client;
use futures::FutureExt;
use tokio::sync::mpsc::channel;
 
use crate::{PubSub};
use crate::backend::mongo::{MongodbPubSub, publish};
 
// You'll want to have some sort of worker which can
// handle incoming messages and deal with them accordingly.
// Here we are just using a channel with predictable data
// so we can just use assert_eq!().
let ( sender, mut receiver ) = channel(100);
 
let client = Client::with_uri_str(&var("MONGODB_URI").unwrap())
    .await
    .unwrap();
 
let mut hive = MongodbPubSub::<i32, i32, String>::new(
    move |_ids, data| {
        let mut s = sender.clone();
        // We just send the data into the channel.
        tokio::spawn(async move {
            s.send(data).await.unwrap();
        });
    },
    client.database("hive").collection("pubsub")
);
 
// We need to subscribe to the topic to get any data.
hive.subscribe(0, 0).unwrap();
 
// Listen to MongoDB collection.
let listener = hive.clone();
let fut = listener.listen().fuse();
 
// We are setting source here to make the hive instance
// accept incoming data. Since `source` is just a String,
// it means we just cloned the original value above and
// are now replacing it.
hive.set_source("1234".to_string());
 
let op = async {
    // Delay so that the other thread can send a message.
    tokio::time::delay_for(tokio::time::Duration::from_secs(2)).await;
 
    // Hence, we publish our data.
    publish(&hive, &0, "The data.".to_string()).await.unwrap();
 
    // And we should receive it back twice.
    assert_eq!(receiver.recv().await.unwrap(), "The data.");
    assert_eq!(receiver.recv().await.unwrap(), "The data.");
}.fuse();
 
futures::pin_mut!(fut, op);
 
futures::select! {
    _ = fut => println!("Listener exited early."),
    _ = op  => println!("Successfully received data back."),
};

Design

Hive is designed to be slotted into any server application to act as a middle-man between you and your clients, it will automatically distribute any notifications you give it to all relevant connected clients and other nodes.

Modules

backend

Structs

Hive

The pubsub client.

Traits

PubSub

PubSub trait which provides common actions.