impulse_server_kit/setup/
port_achiever.rs1use impulse_utils::prelude::*;
4
5pub(crate) async fn port_file_watcher<P: AsRef<std::path::Path>>(path: P) -> MResult<u16> {
6 use notify::{Config, RecommendedWatcher, RecursiveMode, Watcher};
7
8 let (tx, mut rx) = tokio::sync::mpsc::channel(1);
9 let mut watcher = RecommendedWatcher::new(move |res| tx.blocking_send(res).unwrap(), Config::default())
10 .map_err(|e| ServerError::from_private(e).with_500())?;
11 watcher
12 .watch(path.as_ref(), RecursiveMode::NonRecursive)
13 .map_err(|e| ServerError::from_private(e).with_500())?;
14
15 while let Some(res) = rx.recv().await {
16 match res {
17 Ok(event) if event.kind.is_modify() || event.kind.is_create() => {
18 if let Ok(port) = std::fs::read_to_string(path.as_ref())
19 && let Ok(port) = port.trim().parse::<u16>()
20 {
21 watcher
22 .unwatch(path.as_ref())
23 .map_err(|e| ServerError::from_private(e).with_500())?;
24 return Ok(port);
25 }
26 }
27 Err(e) => {
28 tracing::error!("Watch error: {:?}", e);
29 ServerError::from_private(e).with_500().bail()?;
30 }
31 _ => {}
32 }
33 }
34
35 ServerError::from_private_str("Event channel is broken!")
36 .with_500()
37 .bail()
38}