Skip to main content
Glama
state.rs3.26 kB
use std::{ ops::Deref, path::{ Path, PathBuf, }, process::Stdio, sync::Arc, time::Duration, }; use axum::extract::FromRef; use telemetry::tracing::debug; use tokio::{ process::{ Child, Command, }, sync::{ Mutex, mpsc, }, }; use crate::execution::ExecutionError; type Result<T> = std::result::Result<T, ExecutionError>; #[derive(Clone, FromRef)] pub struct AppState { child: LangServerChild, lang_server_process_timeout: LangServerProcessTimeout, telemetry_level: TelemetryLevel, } impl AppState { pub async fn new( lang_server_path: impl Into<PathBuf> + std::convert::AsRef<std::ffi::OsStr>, telemetry_level: Box<dyn telemetry::TelemetryLevel>, lang_server_function_timeout: Option<usize>, lang_server_process_timeout: Option<u64>, ) -> Result<Self> { let mut cmd = Command::new(&lang_server_path); cmd.stdin(Stdio::piped()) .stdout(Stdio::piped()) .stderr(Stdio::piped()); if let Some(timeout) = lang_server_function_timeout { cmd.arg("--timeout").arg(timeout.to_string()); } if telemetry_level.is_debug_or_lower().await { cmd.env("SI_LANG_JS_LOG", "*"); } debug!(cmd = ?cmd, "spawning child process"); let child = cmd .spawn() .map_err(|err| ExecutionError::ChildSpawn(err, lang_server_path.into()))?; Ok(Self { child: LangServerChild(Arc::new(Mutex::new(child))), lang_server_process_timeout: LangServerProcessTimeout(Arc::new( lang_server_process_timeout, )), telemetry_level: TelemetryLevel(Arc::new(telemetry_level)), }) } } #[derive(Clone, Debug, FromRef)] pub struct LangServerPath(Arc<PathBuf>); impl LangServerPath { pub fn as_path(&self) -> &Path { self.0.as_path() } } #[derive(Clone, FromRef)] pub struct TelemetryLevel(Arc<Box<dyn telemetry::TelemetryLevel>>); impl Deref for TelemetryLevel { type Target = Box<dyn telemetry::TelemetryLevel>; fn deref(&self) -> &Self::Target { &self.0 } } #[derive(Clone, Debug, FromRef)] pub struct LangServerFunctionTimeout(Arc<Option<usize>>); impl LangServerFunctionTimeout { pub fn inner(&self) -> Option<usize> { Arc::clone(&self.0).as_ref().to_owned() } } #[derive(Clone, Debug, FromRef)] pub struct LangServerChild(Arc<Mutex<Child>>); impl LangServerChild { pub fn inner(&self) -> Arc<Mutex<Child>> { Arc::clone(&self.0) } } #[derive(Clone, Debug, FromRef)] pub struct LangServerProcessTimeout(Arc<Option<u64>>); impl LangServerProcessTimeout { pub fn inner(&self) -> Option<u64> { Arc::clone(&self.0).as_ref().to_owned() } } pub struct WatchKeepalive { tx: mpsc::Sender<()>, timeout: Duration, } impl WatchKeepalive { pub fn new(tx: mpsc::Sender<()>, timeout: Duration) -> Self { Self { tx, timeout } } pub fn clone_tx(&self) -> mpsc::Sender<()> { self.tx.clone() } /// Gets a reference to the watch keepalive tx's timeout. pub fn timeout(&self) -> Duration { self.timeout } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/systeminit/si'

If you have feedback or need assistance with the MCP directory API, please join our Discord server