use std::error::Error;
use std::fs::File;
use std::io::BufReader;
use std::path::Path;
use clap::Parser;
use hydroflow::lang::graph::{WriteConfig, WriteGraphType};
use peer::run_detector;
use serde::Deserialize;
mod helpers;
mod peer;
mod protocol;
#[derive(Parser, Debug)]
struct Opts {
#[clap(long)]
path: String,
#[clap(long)]
port: u16,
#[clap(long)]
addr: String,
#[clap(long)]
graph: Option<WriteGraphType>,
#[clap(flatten)]
write_config: Option<WriteConfig>,
}
#[derive(Deserialize, Debug)]
struct Addresses {
peers: Vec<String>,
}
fn read_addresses_from_file(path: impl AsRef<Path>) -> Result<Addresses, Box<dyn Error>> {
let file = File::open(path)?;
let reader = BufReader::new(file);
let u = serde_json::from_reader(reader)?;
Ok(u)
}
#[hydroflow::main]
async fn main() {
let opts = Opts::parse();
let path = Path::new(&opts.path);
let peers = read_addresses_from_file(path).unwrap().peers;
run_detector(opts, peers).await;
}
#[test]
fn test() {
use std::io::Write;
use hydroflow::util::{run_cargo_example, wait_for_process_output};
let (_peer1, mut peer1_stdin, mut peer1_stdout) = run_cargo_example(
"deadlock_detector",
&format!(
"--path {}/examples/deadlock_detector/peers.json --addr 127.0.0.1 --port 12346",
env!("CARGO_MANIFEST_DIR")
),
);
let (_peer2, mut peer2_stdin, mut peer2_stdout) = run_cargo_example(
"deadlock_detector",
&format!(
"--path {}/examples/deadlock_detector/peers.json --addr 127.0.0.1 --port 12347",
env!("CARGO_MANIFEST_DIR")
),
);
let (_peer3, mut peer3_stdin, mut peer3_stdout) = run_cargo_example(
"deadlock_detector",
&format!(
"--path {}/examples/deadlock_detector/peers.json --addr 127.0.0.1 --port 12348",
env!("CARGO_MANIFEST_DIR")
),
);
let mut peer3_output = String::new();
wait_for_process_output(
&mut peer3_output,
&mut peer3_stdout,
"Type in an edge as a tuple of two integers \\(x,y\\):",
);
let mut peer1_output = String::new();
wait_for_process_output(
&mut peer1_output,
&mut peer1_stdout,
"Type in an edge as a tuple of two integers \\(x,y\\):",
);
let mut peer2_output = String::new();
wait_for_process_output(
&mut peer2_output,
&mut peer2_stdout,
"Type in an edge as a tuple of two integers \\(x,y\\):",
);
peer1_stdin.write_all(b"(1, 2)\n").unwrap();
peer2_stdin.write_all(b"(2, 3)\n").unwrap();
peer3_stdin.write_all(b"(3, 1)\n").unwrap();
wait_for_process_output(
&mut peer1_output,
&mut peer1_stdout,
"path found: 1 -> 2 -> 3 -> 1",
);
wait_for_process_output(
&mut peer2_output,
&mut peer2_stdout,
"path found: 1 -> 2 -> 3 -> 1",
);
wait_for_process_output(
&mut peer3_output,
&mut peer3_stdout,
"path found: 1 -> 2 -> 3 -> 1",
);
}