msgbus/lib.rs
1#![doc(html_playground_url = "https://play.rust-lang.org/")]
2
3//! Work in Progress - not usable yet!
4//!
5//! # msgbus
6//! `msgbus` provides the ability to publish messages on a channel (or bus) and subscribe to channels to recieve all the messages
7//! published on that channel. To support scalability, when you first register to be able to publish on that channel, you indicate what
8//! kind of bandwidth you will require. The overall message bus is managed by a Message Manager(msgmgr) and that msgmgr will be configured
9//! with various transport capabilities.
10//!
11//! # Theory of Operation
12//! A message bus is a general communication mechanism which has a many-to-many relationship between publishers (many clients can publish on a given bus)
13//! and subscribers (many clients can subscribe to a given bus). In an implementation where we can have many buses, we can have dedicated buses for one-to-one,
14//! one-to-many and many-to-one relationships as needed.
15//!
16//! In this particular implementation, we can have many buses, called `Channels`, and a further enhancement has been added to support scalability. In the
17//! simplest implementation, the publishers and subscribers are threads in a shared application. Communication between them is considered to be high
18//! bandwidth as it can be implemented as shared/copied messages. In a slightly scaled up implementation, the publishers and subscribers may exist in
19//! separate applicaitons on the some processor. This medium bandwith implementation can be implemented as shared memory between those applications or other
20//! local mechanisms. A lower bandwith implementation may have those puclishers and subscribers existing on different connected processors.
21//!
22//! The enhancement to support this is called the `Transport` and is presented as a trait of which we provide several different examples. The clients
23//! (pubblishers or subscribers) don't choose the transport, but rather the bandwidth they require. If during later development, the application must be split
24//! across mulitple processes, or multiple processors, the clients require almost no refactoring as they are independent from the transport.
25//!
26//! # Publishing
27//! Publishing is a non-blocking call to the `msgbus` designated by the `rmb::Channel`. This is a simple `u32` which you define the means for your specific
28//! application. What you send is a structure with the trait of `rmb::Msg`. The msg will be put on the channel, whether there is any subscribers or not.
29//!
30//! # Subscribing
31//! When you subscribe to the a particular channel, your handler will be called for all msgs received from that point forward. The handler may be a function
32//! or closure which you passed to the subscribe call. The handler will be called in the thread context that the msgbus was created in.
33//!
34//! # Simple Example
35//!
36//! ```
37//! use msgbus::{msgmgr,rmb,transport::internal};
38//! use std::fmt;
39//!
40//! fn main() {
41//! struct MyMsg {
42//! s: String,
43//! }
44//! impl rmb::Msg for MyMsg {
45//!
46//! }
47//! impl fmt::Display for MyMsg {
48//! fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49//! write!(f, "{}", self.s)
50//! }
51//! }
52//! fn handler(_chan: rmb::Channel, msg: &dyn rmb::Msg)-> Result<String, String> {
53//! println!("{}", msg);
54//! Ok(msg.to_string())
55//! }
56//!
57//! let t = internal::TransportInternal::new();
58//! let mut mm = msgmgr::MsgMgr::new(vec![(0..10,&t)]);
59//! let mut mb = rmb::Rmb::new(&mut mm);
60//! mb.init().unwrap();
61//! let hello = MyMsg { s: "Hello".to_string() };
62//! let chan = 1;
63//! mb.subscribe(chan, handler).unwrap();
64//! mb.publish(chan, &hello).unwrap();
65//!
66//! }
67pub mod rmb;
68pub mod msgmgr;
69pub mod transport;
70
71#[cfg(test)]
72mod tests {
73 use super::{rmb, msgmgr, transport::local, transport::internal};
74 #[test]
75 fn test_init() {
76 let t = local::TransportLocal::new();
77 let mut mb = msgmgr::MsgMgr::new(vec![(0..10,&t)]);
78 let mut r = rmb::Rmb::new(&mut mb);
79 r.init().unwrap();
80 }
81 #[test]
82 #[ignore]
83 fn test_simple_subscribe_publish() {
84 impl rmb::Msg for String {
85
86 }
87 fn handler(_chan: rmb::Channel, msg: &dyn rmb::Msg)-> Result<String, String> {
88 println!("{}", msg);
89 assert_eq!(msg.to_string(), "Hello".to_string());
90 Ok(msg.to_string())
91 }
92
93 let t = internal::TransportInternal::new();
94 let mut mb = msgmgr::MsgMgr::new(vec![(0..10,&t)]);
95 let mut r = rmb::Rmb::new(&mut mb);
96 r.init().unwrap();
97 let hello = "Hello".to_string();
98 let chan = 1;
99 r.subscribe(chan, handler).unwrap();
100 r.publish(chan, &hello).unwrap();
101 }
102}