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}