Skip to main content

palladium_cli/commands/
stop.rs

1use std::time::{Duration, Instant};
2
3use clap::Args;
4use schemars::JsonSchema;
5use serde::Serialize;
6
7use crate::client::ControlPlaneClient;
8use crate::client::Endpoint;
9use crate::CliResult;
10
11#[derive(Args, Debug, Serialize, JsonSchema)]
12#[serde(rename_all = "kebab-case")]
13pub struct StopArgs {
14    /// Maximum time to wait for graceful shutdown (seconds).
15    #[arg(long, default_value_t = 30)]
16    pub timeout: u64,
17
18    /// Output in JSON format.
19    #[arg(long)]
20    pub json: bool,
21}
22
23pub fn run(args: &StopArgs, endpoint: &Endpoint) -> CliResult {
24    let mut client = ControlPlaneClient::connect_endpoint(endpoint)?;
25    client.call(
26        "engine.stop",
27        serde_json::json!({"timeout_secs": args.timeout}),
28    )?;
29
30    if !args.json {
31        println!("Stop signal sent. Waiting for engine to shut down...");
32    }
33    let deadline = Instant::now() + Duration::from_secs(args.timeout);
34    while Instant::now() < deadline {
35        let stopped = match endpoint {
36            Endpoint::Unix(path) => !path.exists(),
37            _ => true,
38        };
39        if stopped {
40            if args.json {
41                println!(
42                    "{}",
43                    serde_json::json!({
44                        "status": "stopped",
45                        "timeout_secs": args.timeout
46                    })
47                );
48            } else {
49                println!("Engine stopped.");
50            }
51            return Ok(());
52        }
53        std::thread::sleep(Duration::from_millis(200));
54    }
55    Err(format!("Engine did not stop within {}s.", args.timeout).into())
56}