systemprompt_cli/commands/infrastructure/services/restart/
single.rs1use 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}