use std::net::SocketAddr;
use chrono::prelude::*;
use hydroflow::hydroflow_syntax;
use hydroflow::lattices::{Max, Merge};
use hydroflow::util::{UdpSink, UdpStream};
use crate::protocol::EchoMsg;
use crate::Opts;
pub(crate) async fn run_client(outbound: UdpSink, inbound: UdpStream, opts: Opts) {
let server_addr = opts.server_addr.expect("Client requires a server address");
let bot: Max<usize> = Max::new(0);
println!("Client live!");
let mut flow = hydroflow_syntax! {
inbound_chan = source_stream_serde(inbound) -> map(Result::unwrap) -> tee();
outbound_chan = dest_sink_serde(outbound);
inbound_chan[print]
-> for_each(|(m, a): (EchoMsg, SocketAddr)| println!("{}: Got {:?} from {:?}", Utc::now(), m, a));
inbound_chan[merge] -> map(|(msg, _sender): (EchoMsg, SocketAddr)| msg.lamport_clock) -> [net]mergevc;
mergevc = union() -> fold::<'static>(
|| bot,
|old: &mut Max<usize>, lamport_clock: Max<usize>| {
let bump = Max::new(old.into_reveal() + 1);
old.merge(bump);
old.merge(lamport_clock);
}
);
input = source_stdin() -> map(|l| l.unwrap()) -> tee();
input[tick] -> map(|_| bot) -> [input]mergevc;
input[send] -> [0]stamped_output;
mergevc[useful] -> [1]stamped_output;
stamped_output = cross_join::<'tick, 'tick>() -> map(|(l, the_clock): (String, Max<usize>)| (EchoMsg { payload: l, lamport_clock: the_clock }, server_addr));
stamped_output[send] -> outbound_chan;
};
#[cfg(feature = "debugging")]
if let Some(graph) = opts.graph {
let serde_graph = flow
.meta_graph()
.expect("No graph found, maybe failed to parse.");
serde_graph.open_graph(graph, opts.write_config).unwrap();
}
flow.run_async().await.unwrap();
}