Crate instance_chart

source ·
Expand description

Instance chart

Provides data about other instances on the same machine/network

Crates.io Crates.io Docs.rs License

See also:

This crate provides a lightweight alternative to mDNS. It discovers other instances on the same network or (optionally) machine. You provide an Id and some data you want to share. Usually this is a port your service uses. This gives you a live updating chart of all the discovered Ids-data pairs and the corrosponding ip adresses.

The chart can contain instances that are now down. It can not be used to check if a service is up.

Usage

Add a dependency on instance-chart in Cargo.toml:

instance_chart = "0.3"

Now add the following snippet somewhere in your codebase. Discovery will stop when you drop the maintain future.

use std::error::Error;
use instance_chart::{discovery, ChartBuilder};

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
   let chart = ChartBuilder::new()
       .with_id(1) // pick a unique id for each service
       .with_service_port(8042) // The port your service, not discovery, runs on
       .finish()?;
   let maintain = discovery::maintain(chart.clone());
   let _ = tokio::spawn(maintain); // maintain task will run forever
   Ok(())
}

Example App

A minimal peer to peer chat app using instance-chart to discover peers. After type a line the message is sent to all the peers simply by looping over their addresses returned by chart.addr_vec().

#[tokio::main]
async fn main() {
	let listener = TcpListener::bind(("0.0.0.0", 0)).await.unwrap();
	let port = listener.local_addr().unwrap().port();

	let chart = ChartBuilder::new()
		.with_random_id()
		.with_service_port(port)
		.local_discovery(true)
		.finish()
		.unwrap();

	// run these task forever in the background
	let chart2 = chart.clone();
	tokio::spawn(async move { discovery::maintain(chart2).await });
	tokio::spawn(async move { print_incoming(listener).await });

	spawn_blocking(move || {
		let reader = std::io::stdin();
		loop {
			let mut line = String::new();
			reader.read_line(&mut line).unwrap();
			for (_, addr) in chart.addr_vec() {
				let mut peer = std::net::TcpStream::connect(addr).unwrap();
				peer.write_all(line.as_bytes()).unwrap();
			}
		}
	})
	.await
	.unwrap();
}

For the full working example including the print_incoming function see examples/chat.rs.

Modules

Structs

  • The chart keeping track of the discoverd nodes. That a node appears in the chart is no guarentee that it is reachable at this moment.
  • Construct a Chart using a builder-like pattern. You must always set an id. You also need to set service port or service ports. Now you can build with finish or using custom_msg. The latter allowes you to set a custom message to share with other instances when they discover you.
  • Wait for notifications of new discoveries, buffering up to 256 discoveries, created using Chart::notify().

Enums

  • Errors that can occure while building a Chart. Except for Bind these rarely occur.

Type Definitions

  • Identifier for a single instance of Chart. Must be unique.