Skip to main content

systemprompt_cli/commands/infrastructure/services/restart/
single.rs

1use crate::cli_settings::CliConfig;
2use crate::shared::CommandOutput;
3use anyhow::Result;
4use std::sync::Arc;
5use systemprompt_logging::CliService;
6use systemprompt_runtime::AppContext;
7use systemprompt_scheduler::ProcessCleanup;
8
9use super::super::lifecycle;
10use super::super::types::RestartOutput;
11
12pub async fn execute_api(config: &CliConfig) -> Result<CommandOutput> {
13    let quiet = config.is_json_output();
14
15    if !quiet {
16        CliService::section("Restarting API Server");
17    }
18
19    let port = super::get_api_port();
20    let Some(pid) = ProcessCleanup::check_port(port) else {
21        if !quiet {
22            CliService::warning("API server is not running");
23            CliService::info("Starting API server...");
24        }
25        super::super::serve::execute(true, false, config).await?;
26        let output = RestartOutput {
27            service_type: "api".to_owned(),
28            service_name: None,
29            restarted_count: 1,
30            failed_count: 0,
31            message: "API server started (was not running)".to_owned(),
32        };
33        return Ok(CommandOutput::card_value("Restart API Server", &output));
34    };
35
36    if !quiet {
37        CliService::info(&format!("Stopping API server (PID: {})...", pid));
38    }
39
40    ProcessCleanup::terminate_gracefully(pid, 100).await;
41    ProcessCleanup::kill_port(port, pid);
42
43    ProcessCleanup::wait_for_port_free(port, 5, 500).await?;
44
45    if !quiet {
46        CliService::success("API server stopped");
47        CliService::info("Starting API server...");
48    }
49
50    super::super::serve::execute(true, false, config).await?;
51
52    let message = "API server restarted successfully".to_owned();
53    if !quiet {
54        CliService::success(&message);
55    }
56
57    let output = RestartOutput {
58        service_type: "api".to_owned(),
59        service_name: None,
60        restarted_count: 1,
61        failed_count: 0,
62        message,
63    };
64
65    Ok(CommandOutput::card_value("Restart API Server", &output))
66}
67
68pub async fn execute_agent(
69    ctx: &Arc<AppContext>,
70    agent: &str,
71    config: &CliConfig,
72) -> Result<CommandOutput> {
73    let quiet = config.is_json_output();
74
75    if !quiet {
76        CliService::section(&format!("Restarting Agent: {}", agent));
77    }
78
79    let orchestrator = lifecycle::agent_orchestrator(ctx).await?;
80    let name = lifecycle::resolve_agent_name(agent).await?;
81    let service_id = orchestrator.restart_agent(&name, None).await?;
82
83    let message = format!(
84        "Agent {} restarted successfully (service ID: {})",
85        agent, service_id
86    );
87    if !quiet {
88        CliService::success(&message);
89    }
90
91    let output = RestartOutput {
92        service_type: "agent".to_owned(),
93        service_name: Some(agent.to_owned()),
94        restarted_count: 1,
95        failed_count: 0,
96        message,
97    };
98
99    Ok(CommandOutput::card_value("Restart Agent", &output))
100}
101
102pub async fn execute_mcp(
103    ctx: &Arc<AppContext>,
104    server_name: &str,
105    build: bool,
106    config: &CliConfig,
107) -> Result<CommandOutput> {
108    let quiet = config.is_json_output();
109    let action = if build {
110        "Building and restarting"
111    } else {
112        "Restarting"
113    };
114
115    if !quiet {
116        CliService::section(&format!("{} MCP Server: {}", action, server_name));
117    }
118
119    let manager = lifecycle::mcp_orchestrator(ctx)?;
120
121    if build {
122        manager
123            .build_and_restart_services(Some(server_name.to_owned()))
124            .await?;
125    } else {
126        manager
127            .restart_services_sync(Some(server_name.to_owned()))
128            .await?;
129    }
130
131    let message = format!("MCP server {} restarted successfully", server_name);
132    if !quiet {
133        CliService::success(&message);
134    }
135
136    let output = RestartOutput {
137        service_type: "mcp".to_owned(),
138        service_name: Some(server_name.to_owned()),
139        restarted_count: 1,
140        failed_count: 0,
141        message,
142    };
143
144    Ok(CommandOutput::card_value("Restart MCP Server", &output))
145}