syncweb_core/daemon/
route.rs1use std::path::Path;
2
3use crate::error::Result;
4
5use super::{DaemonStatus, IpcClient, PidLock};
6
7pub fn daemon_client(data_dir: &Path) -> Result<Option<IpcClient>> {
13 let lock = PidLock::new(data_dir);
14 if lock.try_acquire()? {
15 lock.release()?;
16 return Ok(None);
17 }
18 let client = IpcClient::new(data_dir);
19 match client.status_sync() {
20 Ok(DaemonStatus::Starting | DaemonStatus::Running) => Ok(Some(client)),
21 Ok(_) | Err(_) => Ok(None),
22 }
23}
24
25pub fn try_daemon(data_dir: &Path) -> Result<Option<IpcClient>> {
31 daemon_client(data_dir)
32}
33
34pub async fn with_node<F, R>(data_dir: &Path, operation: F) -> Result<R>
43where
44 F: FnOnce(IpcClient) -> R,
45{
46 let client = daemon_client(data_dir)?
47 .ok_or_else(|| crate::error::SyncwebError::operation("daemon not running", "start with `syncweb start`"))?;
48 let result = operation(client);
49 Ok(result)
50}
51
52#[cfg(test)]
53mod tests {
54 use super::*;
55
56 #[test]
57 fn daemon_client_returns_none_when_no_lock() {
58 let dir = std::env::temp_dir().join(format!("syncweb-route-test-{}", uuid::Uuid::new_v4()));
59 std::fs::create_dir_all(&dir).unwrap();
60 let result = daemon_client(&dir);
61 assert!(result.is_ok());
62 assert!(result.unwrap().is_none());
63 let _ = std::fs::remove_dir_all(&dir);
64 }
65
66 #[test]
67 fn try_daemon_returns_none_when_no_lock() {
68 let dir = std::env::temp_dir().join(format!("syncweb-route-test-{}", uuid::Uuid::new_v4()));
69 std::fs::create_dir_all(&dir).unwrap();
70 let result = try_daemon(&dir);
71 assert!(result.is_ok());
72 assert!(result.unwrap().is_none());
73 let _ = std::fs::remove_dir_all(&dir);
74 }
75
76 #[cfg(unix)]
77 #[test]
78 fn daemon_client_live_pid_with_dead_socket_returns_none() {
79 let dir = std::env::temp_dir().join(format!("syncweb-route-socket-{}", uuid::Uuid::new_v4()));
80 std::fs::create_dir_all(&dir).unwrap();
81 let lock = PidLock::new(&dir);
82 assert!(lock.try_acquire().unwrap());
83 let result = daemon_client(&dir);
84 lock.release().unwrap();
85 assert!(result.is_ok());
86 assert!(result.unwrap().is_none());
87 let _ = std::fs::remove_dir_all(&dir);
88 }
89
90 #[cfg(unix)]
91 #[test]
92 fn daemon_client_status_ping_timeout_returns_none() {
93 let dir = std::env::temp_dir().join(format!("syncweb-route-timeout-{}", uuid::Uuid::new_v4()));
94 std::fs::create_dir_all(&dir).unwrap();
95 let lock = PidLock::new(&dir);
96 assert!(lock.try_acquire().unwrap());
97 let result = daemon_client(&dir);
98 lock.release().unwrap();
99 assert!(result.is_ok());
100 assert!(result.unwrap().is_none());
101 let _ = std::fs::remove_dir_all(&dir);
102 }
103}