use std::path::PathBuf;
use crate::context::Context;
use crate::error::Error;
pub async fn kill_lock_owners(locks_dir: PathBuf, key: &str) -> Result<usize, Error> {
let pids = objectiveai_sdk::lockfile::owners(&locks_dir, key)
.await
.map_err(|e| Error::Spawn(format!("read lock owners for {key}"), e))?;
let mut killed = 0;
for pid in pids {
killed += crate::spawn::kill_pid(pid);
}
Ok(killed)
}
pub async fn kill_per_state(
ctx: &Context,
scope: objectiveai_sdk::cli::command::SetScope,
key: &'static str,
) -> Result<usize, Error> {
match scope {
objectiveai_sdk::cli::command::SetScope::State => {
let locks_dir = ctx.filesystem.state_dir().join("locks");
kill_lock_owners(locks_dir, key).await
}
objectiveai_sdk::cli::command::SetScope::Global => {
let states_root = ctx.filesystem.dir().join("state");
let mut dirs: Vec<PathBuf> = Vec::new();
match tokio::fs::read_dir(&states_root).await {
Ok(mut rd) => {
while let Some(entry) = rd
.next_entry()
.await
.map_err(|e| Error::Spawn("list states".to_string(), e))?
{
if entry
.file_type()
.await
.map(|t| t.is_dir())
.unwrap_or(false)
{
dirs.push(entry.path().join("locks"));
}
}
}
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {}
Err(e) => return Err(Error::Spawn("open state dir".to_string(), e)),
}
let results = futures::future::join_all(
dirs.into_iter().map(|d| kill_lock_owners(d, key)),
)
.await;
let mut total = 0;
for r in results {
total += r?;
}
Ok(total)
}
}
}