62a65b691d
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
59 lines
1.9 KiB
Rust
59 lines
1.9 KiB
Rust
mod launchd;
|
|
mod lifecycle;
|
|
mod persist;
|
|
mod registry;
|
|
mod server;
|
|
mod state_store;
|
|
mod surface;
|
|
|
|
use anyhow::Result;
|
|
|
|
/// Test-only support shared across the crate's test modules.
|
|
#[cfg(test)]
|
|
pub(crate) mod test_support {
|
|
use std::sync::{Mutex, MutexGuard};
|
|
|
|
/// Process-wide serialization lock for the heavy socket/PTY integration tests.
|
|
/// These bind sockets and spawn real PTYs/processes; running several at once on a
|
|
/// many-core box starves each other's tasks and trips timing assumptions. Unit
|
|
/// tests stay parallel; only guarded integration tests serialize on this lock.
|
|
static SERIAL: Mutex<()> = Mutex::new(());
|
|
|
|
/// Acquire the serial lock for the duration of a test. Poison-tolerant so one
|
|
/// panicking test does not cascade-fail the rest.
|
|
pub(crate) fn serial() -> MutexGuard<'static, ()> {
|
|
SERIAL.lock().unwrap_or_else(|e| e.into_inner())
|
|
}
|
|
}
|
|
|
|
#[tokio::main]
|
|
async fn main() -> Result<()> {
|
|
let arg = std::env::args().nth(1);
|
|
match arg.as_deref() {
|
|
Some("install-agent") => {
|
|
launchd::install_agent()?;
|
|
println!("launchd agent installed");
|
|
Ok(())
|
|
}
|
|
Some("--help") | Some("-h") => {
|
|
println!("spaceshd [install-agent]");
|
|
Ok(())
|
|
}
|
|
_ => run_daemon().await,
|
|
}
|
|
}
|
|
|
|
async fn run_daemon() -> Result<()> {
|
|
let Some(_lock) = lifecycle::acquire_instance_lock()? else {
|
|
eprintln!("another spaceshd is already running");
|
|
return Ok(());
|
|
};
|
|
lifecycle::clear_stale_socket()?;
|
|
let sock = lifecycle::socket_path()?;
|
|
let state_path = lifecycle::spacesh_dir()?.join("state.json");
|
|
let store: std::sync::Arc<dyn state_store::StateStore> =
|
|
std::sync::Arc::new(state_store::JsonStateStore::new(state_path));
|
|
eprintln!("spaceshd listening on {}", sock.display());
|
|
server::serve(&sock, store).await
|
|
}
|