session_probe/
session_probe.rs1use std::io::BufRead;
14use std::process::{Command, Stdio};
15use std::time::{Duration, Instant};
16
17use rich_web::intuituive::prelude::*;
18
19fn app() -> App {
20 App::new(|| {
21 let pid = std::process::id();
22 let state = signal(String::from("waiting"));
23 column([
24 text!("pid {pid} · {state}").fixed(1),
25 label("f forks · n nested").fixed(1),
26 ])
27 .on_key("f", move |_| {
28 #[allow(clippy::zombie_processes)]
30 let child = long_wait().spawn().unwrap();
31 state.set(format!("FORKED {} END", child.id()));
32 })
33 .on_key("n", move |_| {
34 let out = Command::new(std::env::current_exe().unwrap())
36 .args(["--nested", "127.0.0.1:0"])
37 .stdin(Stdio::null())
38 .output()
39 .unwrap();
40 let code = out.status.code().unwrap_or(-1);
41 let bound = String::from_utf8_lossy(&out.stdout).contains("BOUND");
42 state.set(format!("NESTED code={code} bound={bound} END"));
43 })
44 })
45}
46
47#[cfg(not(windows))]
49fn long_wait() -> Command {
50 let mut command = Command::new("sleep");
51 command.arg("1000");
52 command
53}
54
55#[cfg(windows)]
57fn long_wait() -> Command {
58 let mut command = Command::new("ping");
59 command
60 .args(["-n", "1000", "127.0.0.1"])
61 .stdout(Stdio::null());
62 command
63}
64
65fn main() -> std::io::Result<()> {
66 let mut args = std::env::args().skip(1);
67 let mut addr = "127.0.0.1:8080".to_string();
68 let mut token = None;
69 let mut startup = None;
70 let mut stdin_stop = false;
71 let mut nested = false;
72 while let Some(arg) = args.next() {
73 let mut value = || args.next().expect("a value after the option");
74 match arg.as_str() {
75 "--token" => token = Some(value()),
76 "--startup-sleep" => startup = Some(value().parse::<u64>().expect("ms")),
77 "--stdin-stop" => stdin_stop = true,
78 "--nested" => nested = true,
79 _ => addr = arg,
80 }
81 }
82 if nested {
83 let server = rich_web::Server::bind(addr.as_str(), app)?;
86 println!("BOUND {}", server.local_addr());
87 return Ok(());
88 }
89 if let (Some(ms), true) = (startup, std::env::var_os(rich_web::SESSION_ENV).is_some()) {
90 std::thread::sleep(Duration::from_millis(ms));
91 }
92 let mut server = rich_web::Server::bind(addr.as_str(), app)?.title("session probe");
93 if let Some(token) = token {
94 server = server.token(token);
95 }
96 if stdin_stop {
97 let handle = server.spawn()?;
98 println!("Serving session probe at {}", handle.url());
99 let mut line = String::new();
100 std::io::stdin().lock().read_line(&mut line)?;
101 let started = Instant::now();
102 handle.stop();
103 println!("STOPPED {}", started.elapsed().as_millis());
104 return Ok(());
105 }
106 server.run()
107}