1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
//! Netidx is like DNS for values. With netidx you can name individual //! values in your program, and other programs can find and subscribe //! to those values securely over the network. //! //! Like DNS netidx maintains a hierarchical namespace in a resolver //! server. Publishers tell the resolver about values they //! have. Subscribers ask the resolver for values they want. Once a //! subscriber knows where to find a value it is looking for, it //! connects directly to the publisher, and the resolver is no longer //! involved. //! //! # Publisher //! ```no_run //! # fn get_cpu_temp() -> f32 { 42. } //! use netidx::{ //! publisher::{Publisher, Value, BindCfg}, //! config::Config, //! resolver::Auth, //! path::Path, //! }; //! use tokio::time; //! use std::time::Duration; //! //! # use anyhow::Result; //! # async fn run() -> Result<()> { //! // load the site cluster config. You can also just use a file. //! let cfg = Config::load_default()?; //! //! // no authentication (kerberos v5 is the other option) //! // listen on any unique address matching 192.168.0.0/16 //! let publisher = Publisher::new(cfg, Auth::Anonymous, "192.168.0.0/16".parse()?).await?; //! //! let temp = publisher.publish( //! Path::from("/hw/washu-chan/cpu-temp"), //! Value::F32(get_cpu_temp()) //! )?; //! publisher.flush(None).await; //! //! loop { //! time::sleep(Duration::from_millis(500)).await; //! temp.update(Value::F32(get_cpu_temp())); //! publisher.flush(None).await; //! } //! # Ok(()) //! # }; //! ``` //! //! # Subscriber //! ```no_run //! use netidx::{ //! subscriber::Subscriber, //! config::Config, //! resolver::Auth, //! path::Path, //! }; //! use futures::{prelude::*, channel::mpsc}; //! # use anyhow::Result; //! //! # async fn run() -> Result<()> { //! let cfg = Config::load_default()?; //! let subscriber = Subscriber::new(cfg, Auth::Anonymous)?; //! let path = Path::from("/hw/washu-chan/cpu-temp"); //! let temp = subscriber.subscribe_one(path, None).await?; //! println!("washu-chan cpu temp is: {:?}", temp.last()); //! //! let (tx, mut rx) = mpsc::channel(10); //! temp.updates(false, tx); //! while let Some(mut batch) = rx.next().await { //! for (_, v) in batch.drain(..) { //! println!("washu-chan cpu temp is: {:?}", v); //! } //! } //! # Ok(()) //! # }; //! ``` //! //! Published values always have a value, and new subscribers receive //! the most recent published value initially. Thereafter a //! subscription is a lossless ordered stream, just like a tcp //! connection, except that instead of bytes `publisher::Value` is the //! unit of transmission. Since the subscriber can write values back //! to the publisher, the connection is bidirectional, also like a Tcp //! stream. //! //! Values include many useful primitives, including zero copy bytes //! buffers (using the awesome bytes crate), so you can easily use //! netidx to efficiently send any kind of message you like. However //! it's advised to stick to primitives and express structure with //! muliple published values in a hierarchy, since this makes your //! system more discoverable, and is also quite efficient. //! //! In many environments security is a requirement, whereas in others //! it's not necessary. To handle both of these cases netidx includes //! optional support for kerberos v5 (including Active Directory). If //! enabled, all components will do mutual authentication between the //! resolver, subscriber, and publisher as well as encryption of all //! data on the wire. In addition to authentication, the resolver //! server in krb5 mode maintains and enforces authorization //! permissions for the entire namespace, so the resolvers can //! centrally enforce who can publish where, and who can subscribe to //! what. //! //! * Publish with a [`Publisher`](publisher/struct.Publisher.html) //! * Subscribe with a [`Subscriber`](subscriber/struct.Subscriber.html) #![recursion_limit = "1024"] #[macro_use] extern crate lazy_static; #[macro_use] extern crate serde_derive; #[macro_use] extern crate bitflags; #[macro_use] extern crate anyhow; #[macro_use] extern crate netidx_core; pub use netidx_core::{chars, pack, pool, path, utils}; pub use netidx_netproto as protocol; mod batch_channel; mod auth; mod channel; pub mod config; mod os; pub mod publisher; pub mod resolver; pub mod resolver_server; mod resolver_single; mod shard_resolver_store; mod resolver_store; mod secstore; pub mod subscriber; #[cfg(test)] mod test;