Suppress errors for requested session stops

This commit is contained in:
iris committed 2026-09-12 20:49:38 -04:00
1 parent 76895bc644
commit 559e6c9226
5 files changed
+101 -18

No files matched your search

+32 -5
View File
@@ -30,6 +30,7 @@ use anyhow::{Context, Result};
use serde::{Deserialize, Serialize};
const RECORD_FILE: &str = "process.json";
const STOP_REQUEST_FILE: &str = "stop-requested";
/// A process this server started and expects to outlive it.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
@@ -101,6 +102,28 @@ fn path(session_dir: &Path) -> PathBuf {
session_dir.join(RECORD_FILE)
}
fn stop_request_path(session_dir: &Path) -> PathBuf {
session_dir.join(STOP_REQUEST_FILE)
}
/// Marks the process as one the server deliberately asked to end, so its watcher reports an exit
/// without presenting ordinary stderr from the process's lifetime as the cause.
pub fn mark_stopping(session_dir: &Path) -> Result<()> {
std::fs::OpenOptions::new()
.create(true)
.write(true)
.truncate(true)
.mode(0o600)
.open(stop_request_path(session_dir))
.with_context(|| format!("marking {} as stopping", session_dir.display()))?;
Ok(())
}
/// Whether this process's exit was deliberately requested.
pub fn stopping(session_dir: &Path) -> bool {
stop_request_path(session_dir).is_file()
}
/// The recorded process and whether it is still there, or `None` when nothing
/// usable is recorded. A record that does not parse reads as no record: the
/// only way to get one is a crash partway through writing it, and the safe
@@ -179,11 +202,12 @@ pub fn size_of(path: &Path) -> u64 {
/// Forgets the recorded process -- for one confirmed dead, or a session
/// being deleted. The path out for [`write`].
pub fn clear(session_dir: &Path) {
let path = path(session_dir);
if let Err(err) = std::fs::remove_file(&path)
&& err.kind() != std::io::ErrorKind::NotFound
{
tracing::warn!("couldn't remove {}: {err}", path.display());
for path in [path(session_dir), stop_request_path(session_dir)] {
if let Err(err) = std::fs::remove_file(&path)
&& err.kind() != std::io::ErrorKind::NotFound
{
tracing::warn!("couldn't remove {}: {err}", path.display());
}
}
}
@@ -405,8 +429,11 @@ mod tests {
write(dir.path(), &record);
assert_eq!(live(dir.path()), Some(record));
mark_stopping(dir.path()).expect("mark stopping");
assert!(stopping(dir.path()));
clear(dir.path());
assert_eq!(live(dir.path()), None);
assert!(!stopping(dir.path()));
}
#[test]