Skip to main content

plate_spinner/
lib.rs

1pub mod cli;
2pub mod config;
3pub mod daemon;
4pub mod db;
5pub mod hook;
6pub mod models;
7pub mod recovery;
8pub mod state_machine;
9pub mod tui;
10
11use std::process::Command;
12
13pub fn build_version() -> String {
14    let version = env!("CARGO_PKG_VERSION");
15    if cfg!(debug_assertions) {
16        format!("{}-dev+{}", version, env!("BUILD_TIMESTAMP"))
17    } else {
18        version.to_string()
19    }
20}
21
22fn kill_daemon() {
23    let client = reqwest::blocking::Client::new();
24    let _ = client
25        .post(format!("{}/shutdown", hook::DAEMON_URL))
26        .timeout(std::time::Duration::from_secs(1))
27        .send();
28    std::thread::sleep(std::time::Duration::from_millis(500));
29}
30
31fn spawn_daemon() {
32    let exe = std::env::current_exe().unwrap_or_else(|_| "sp".into());
33    Command::new(&exe)
34        .arg("daemon")
35        .stdout(std::process::Stdio::null())
36        .stderr(std::process::Stdio::null())
37        .spawn()
38        .ok();
39    std::thread::sleep(std::time::Duration::from_secs(1));
40}
41
42pub fn ensure_daemon_running() {
43    let client = reqwest::blocking::Client::new();
44    let my_version = build_version();
45
46    let response = client
47        .get(format!("{}/health", hook::DAEMON_URL))
48        .timeout(std::time::Duration::from_secs(1))
49        .send()
50        .ok()
51        .and_then(|r| r.json::<serde_json::Value>().ok());
52
53    match response {
54        Some(json) => {
55            let daemon_version = json.get("version").and_then(|v| v.as_str());
56            if daemon_version != Some(&my_version) {
57                kill_daemon();
58                spawn_daemon();
59            }
60        }
61        None => {
62            spawn_daemon();
63        }
64    }
65}