mail4agent_messenger_shell/cli/
web_client.rs1use crate::MachineClient;
17use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
18
19fn env_secs(key: &str, default: u64) -> u64 {
20 std::env::var(key)
21 .ok()
22 .and_then(|value| value.parse().ok())
23 .unwrap_or(default)
24}
25
26fn now_ms() -> i64 {
27 SystemTime::now()
28 .duration_since(UNIX_EPOCH)
29 .map(|elapsed| elapsed.as_millis() as i64)
30 .unwrap_or(0)
31}
32
33pub fn run(_args: Vec<String>) {
34 crate::load_env_file();
35 let mut client = match MachineClient::from_env() {
36 Ok(client) => client,
37 Err(err) => {
38 eprintln!("open failed: {err}");
39 std::process::exit(1);
40 }
41 };
42 match client.listen_for_sends_from_env() {
43 Ok(path) => println!("send socket {}", path.display()),
44 Err(err) => eprintln!("send socket not opened: {err}"),
45 }
46 println!("open ok; waiting on the push socket");
47 let drive_secs = env_secs("M4A_DRIVE_SECS", 15);
48 let run_secs = env_secs("M4A_RUN_SECS", 0);
49 let started = Instant::now();
50 let mut seen = 0usize;
51 loop {
52 let report = client.tick(now_ms(), drive_secs);
53 for (nick, event_id) in &report.pushed {
54 println!("push {nick} event={event_id}");
55 }
56 for (nick, text) in &report.alerts {
57 println!("alert {nick}: {text}");
58 }
59 for (nick, room) in &report.joined {
60 println!("joined {nick} room={room}");
61 }
62 for (from, to, reply) in &report.sent {
63 match (&reply.event_id, &reply.error) {
64 (_, Some(err)) => println!("send {from} -> {to} failed: {err}"),
65 (Some(event_id), None) => println!("send {from} -> {to} event={event_id}"),
66 (None, None) => println!("send {from} -> {to} ok"),
67 }
68 }
69 for (nick, err) in &report.errors {
70 eprintln!("drive {nick}: {err}");
71 }
72 let log = client.wake_log();
73 for (nick, attempt) in log.iter().skip(seen) {
74 let status = attempt
75 .status
76 .map(|code| code.to_string())
77 .unwrap_or_else(|| "none".to_string());
78 println!("wake {nick} event={} status={status}", attempt.event_id);
79 }
80 seen = log.len();
81 if let Err(err) = client.poll_agent_directory() {
82 eprintln!("agent poll: {err}");
83 }
84 if run_secs > 0 && started.elapsed().as_secs() >= run_secs {
85 println!("run time reached; exiting");
86 break;
87 }
88 std::thread::sleep(Duration::from_millis(250));
89 }
90}