Keep file-watch observation from serializing unrelated IO
Scope open-registration and rename/remove ordering to overlapping paths; let descriptor mutations and directory creation proceed without that lock. Prove blocked opens/writes cannot stall unrelated namespaces, including a queued rename, and retain post-rename descriptor notifications. Document handler-owned watch lifetimes and narrow paths; test natural idle exit. Card: SAU-359
This commit is contained in:
@@ -63,6 +63,41 @@ impl Probe {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Poll the watch in the handler, then return idle without a background task.
|
||||
async fn watch_once(&self, p: WatchPath) -> Result<()> {
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
rc::Rc,
|
||||
task::{Poll, Waker},
|
||||
};
|
||||
let state = Rc::new(RefCell::new((false, None::<Waker>)));
|
||||
let received = state.clone();
|
||||
let mut watch = std::pin::pin!(std::future::IntoFuture::into_future(
|
||||
call("core.watch", json!({"path":p.path})).on_notify(move |name, _| {
|
||||
if name == "armed" {
|
||||
let mut state = received.borrow_mut();
|
||||
state.0 = true;
|
||||
if let Some(waker) = state.1.take() {
|
||||
waker.wake();
|
||||
}
|
||||
}
|
||||
})
|
||||
));
|
||||
std::future::poll_fn(|cx| {
|
||||
if let Poll::Ready(result) = watch.as_mut().poll(cx) {
|
||||
return Poll::Ready(result.map(|_| ()));
|
||||
}
|
||||
let mut state = state.borrow_mut();
|
||||
state.1 = Some(cx.waker().clone());
|
||||
if state.0 {
|
||||
Poll::Ready(Ok(()))
|
||||
} else {
|
||||
Poll::Pending
|
||||
}
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
/// Publish a control endpoint until EOF.
|
||||
async fn serve(&self) -> Result<()> {
|
||||
sausage_plugin::listen("/endpoint", std::rc::Rc::new(Control)).await
|
||||
|
||||
Reference in New Issue
Block a user