use instance_chart::{discovery, ChartBuilder};
use std::io::Write;
use tokio::io::AsyncBufReadExt;
use tokio::io::BufReader;
use tokio::net::TcpListener;
use tokio::task;
use tokio::task::spawn_blocking;
use instance_chart;
async fn print_user(stream: tokio::net::TcpStream, user: String) {
let mut reader = BufReader::new(stream);
let mut line = String::new();
reader.read_line(&mut line).await.unwrap();
print!("\t{user}: {line}");
}
async fn print_incoming(listener: TcpListener) {
while let Ok((stream, peer_addr)) = listener.accept().await {
task::spawn(async move {
print_user(stream, peer_addr.to_string()).await;
});
}
}
fn setup_tracing() {
use tracing_subscriber::{filter, prelude::*};
let filter = filter::EnvFilter::builder()
.parse("info,instance_chart=debug")
.unwrap();
let fmt = tracing_subscriber::fmt::layer().pretty().with_test_writer();
let _ignore_err = tracing_subscriber::registry()
.with(filter)
.with(fmt)
.try_init();
}
#[tokio::main]
async fn main() {
setup_tracing();
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();
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();
unreachable!()
}