Skip to main content

systemprompt_models/repository/
service.rs

1use anyhow::{Result, anyhow};
2use async_trait::async_trait;
3use serde::{Deserialize, Serialize};
4use systemprompt_traits::RepositoryError;
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
7pub struct ServiceRecord {
8    pub name: String,
9    pub module_name: String,
10    pub status: String,
11    pub pid: Option<i32>,
12    pub port: i32,
13}
14
15impl ServiceRecord {
16    pub fn from_json_row(
17        row: &std::collections::HashMap<String, serde_json::Value>,
18    ) -> Result<Self> {
19        let name = row
20            .get("name")
21            .and_then(|v| v.as_str())
22            .ok_or_else(|| anyhow!("Missing name"))?
23            .to_string();
24
25        let module_name = row
26            .get("module_name")
27            .and_then(|v| v.as_str())
28            .ok_or_else(|| anyhow!("Missing module_name"))?
29            .to_string();
30
31        let status = row
32            .get("status")
33            .and_then(|v| v.as_str())
34            .ok_or_else(|| anyhow!("Missing status"))?
35            .to_string();
36
37        let pid = row
38            .get("pid")
39            .and_then(serde_json::Value::as_i64)
40            .and_then(|i| i32::try_from(i).ok());
41
42        let port = row
43            .get("port")
44            .and_then(serde_json::Value::as_i64)
45            .ok_or_else(|| anyhow!("Missing port"))
46            .and_then(|i| i32::try_from(i).map_err(|_| anyhow!("Port out of range")))?;
47
48        Ok(Self {
49            name,
50            module_name,
51            status,
52            pid,
53            port,
54        })
55    }
56}
57
58#[async_trait]
59pub trait ServiceLifecycle: Send + Sync {
60    async fn get_running_services(&self) -> Result<Vec<ServiceRecord>, RepositoryError>;
61    async fn mark_crashed(&self, service_name: &str) -> Result<(), RepositoryError>;
62    async fn update_status(&self, service_name: &str, status: &str) -> Result<(), RepositoryError>;
63}