systemprompt_cli/commands/infrastructure/services/restart/
single.rs1use crate::cli_settings::CliConfig;
2use crate::shared::CommandResult;
3use anyhow::{Context, Result};
4use std::sync::Arc;
5use systemprompt_logging::CliService;
6use systemprompt_mcp::services::McpManager;
7use systemprompt_runtime::AppContext;
8use systemprompt_scheduler::ProcessCleanup;
9
10use super::super::types::RestartOutput;
11
12pub async fn execute_api(config: &CliConfig) -> Result<CommandResult<RestartOutput>> {
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_string(),
28 service_name: None,
29 restarted_count: 1,
30 failed_count: 0,
31 message: "API server started (was not running)".to_string(),
32 };
33 return Ok(CommandResult::card(output).with_title("Restart API Server"));
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);
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_string();
53 if !quiet {
54 CliService::success(&message);
55 }
56
57 let output = RestartOutput {
58 service_type: "api".to_string(),
59 service_name: None,
60 restarted_count: 1,
61 failed_count: 0,
62 message,
63 };
64
65 Ok(CommandResult::card(output).with_title("Restart API Server"))
66}
67
68pub async fn execute_agent(
69 ctx: &Arc<AppContext>,
70 agent: &str,
71 config: &CliConfig,
72) -> Result<CommandResult<RestartOutput>> {
73 let quiet = config.is_json_output();
74
75 if !quiet {
76 CliService::section(&format!("Restarting Agent: {}", agent));
77 }
78
79 let orchestrator = super::create_orchestrator(ctx).await?;
80 let name = super::resolve_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_string(),
93 service_name: Some(agent.to_string()),
94 restarted_count: 1,
95 failed_count: 0,
96 message,
97 };
98
99 Ok(CommandResult::card(output).with_title("Restart Agent"))
100}
101
102pub async fn execute_mcp(
103 ctx: &Arc<AppContext>,
104 server_name: &str,
105 build: bool,
106 config: &CliConfig,
107) -> Result<CommandResult<RestartOutput>> {
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 =
120 McpManager::new(Arc::clone(ctx.db_pool())).context("Failed to initialize MCP manager")?;
121
122 if build {
123 manager
124 .build_and_restart_services(Some(server_name.to_string()))
125 .await?;
126 } else {
127 manager
128 .restart_services_sync(Some(server_name.to_string()))
129 .await?;
130 }
131
132 let message = format!("MCP server {} restarted successfully", server_name);
133 if !quiet {
134 CliService::success(&message);
135 }
136
137 let output = RestartOutput {
138 service_type: "mcp".to_string(),
139 service_name: Some(server_name.to_string()),
140 restarted_count: 1,
141 failed_count: 0,
142 message,
143 };
144
145 Ok(CommandResult::card(output).with_title("Restart MCP Server"))
146}