Files
sausage/sdk/src/locks.rs
T
surma c728429d04 sdk, agent: review fixes (T18R)
- The serve loop ends the process after EOF or exit_after_response,
  also with background tasks or listeners.
- One schema generator per direction for the whole document, so types
  with the same name get distinct names.
- The agent gives the complete error (code, message, data) to the
  model, writes SKIP only after a successful request, caps tool output
  at 64 KiB, writes each history line in one write, and skips a damaged
  line.
- Endpoints skip blank and non-RPC lines. client_rs does not panic.
- #[must_use] on builders and the lock guard; #[schemars] attributes
  and duplicate hooks are compile errors; raw identifiers; -32000 for
  local SDK errors; x-sausage-params only for methods with params.
2026-10-23 02:38:35 +01:00

68 lines
1.8 KiB
Rust

//! Advisory lock acquisition and guard lifetime.
use super::*;
/// An advisory lock acquisition.
#[must_use = "await the lock to acquire it"]
pub struct Lock {
path: String,
wait: bool,
}
/// Acquire an advisory lock on a path.
pub fn lock(path: impl AsRef<Path>) -> Lock {
Lock {
path: path.as_ref().to_string_lossy().into_owned(),
wait: true,
}
}
impl Lock {
/// Return immediately, without waiting for a held lock.
pub fn try_now(mut self) -> Self {
self.wait = false;
self
}
}
/// Releases its lock on drop, unless kept until process exit.
#[must_use = "bind the guard to hold the lock"]
pub struct Guard {
path: Option<String>,
}
impl Guard {
/// Hold this lock until process exit.
pub fn keep(mut self) {
self.path.take();
}
/// Report whether this guard holds the lock.
pub fn held(&self) -> bool {
self.path.is_some()
}
}
impl Drop for Guard {
fn drop(&mut self) {
if let Some(path) = self.path.take() {
let _ = notify("core.unlock", json!({"path":path}));
}
}
}
impl IntoFuture for Lock {
type Output = Result<Guard>;
type IntoFuture = LocalBoxFuture<'static, Self::Output>;
fn into_future(self) -> Self::IntoFuture {
Box::pin(async move {
let lease = std::rc::Rc::new(Lease {
path: self.path.clone(),
held: std::cell::Cell::new(false),
});
let mut c = call("core.lock", json!({"path":self.path,"wait":self.wait}));
c.unlock = Some(lease.clone());
let result = c.await?;
lease.held.set(false);
Ok(Guard {
path: if result["held"] == true {
Some(self.path)
} else {
None
},
})
})
}
}