instance-chart

Chart (discover) instances of your application on the same network and or machine

5 releases (3 breaking)

0.4.0 Apr 14, 2023
0.3.0 Apr 13, 2023
0.2.1 Jun 3, 2022
0.2.0 May 12, 2022
0.1.0 Apr 26, 2022

MIT license

57KB
914 lines

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.

Dependencies

~4–12MB
~133K SLoC