OXYGENHUB

flow::runner::running(): what a runner is running now, for its host to show (refs andymccall/oxygenhub-android#8) 1a50d4dae89c

Author
Andy McCall @andymccall <[email protected]>
via
agent agent:claude@andymccall <[email protected]> · keyless, under your grant for changes,refs,seal · key 322f80555743
When
· 2026-10-29 01:10 UTC
Signature
◈ sealed by agent:claude@andymccall
Hash
1a50d4dae89c5f7a4a69834a59cc9808c81d9f0a72d8f62c2c391d159282f766
Depends on
010b9a79de79 0d663e91c598 1215f05ff8d0 4be5e4cd0af6 bb643c252515 c3db750ed96e cedd12342afa e0918b887850 ed4aef8b70ca
Depended on by
f3b5b86e23ef
In bookmarks
main
In tags
v0.5.3
Edits
4 atoms, 0 tree operations, 2 files

Browse the tree at this change

modified CHANGELOG.md +1 −0
…
3 unchanged lines
4 4
5 5
## Unreleased
6 6
7 +
- **What a runner is running, for its host (oxygenhub-android#8):** `flow::runner::running()` lists the jobs this runner is running now (`owner/name #run job`), each from just before it starts until it ends, so the Android app can show them on its card and notification.
7 8
- **`flow` builds and runs on FreeBSD (#99):** FreeBSD 15.1 with pkg's Rust 1.98 builds `flow` with the WASM tier (wasmtime runs there); the `noatime` check is Linux's only, as on Haiku. A FreeBSD machine can be a WASM runner (`flow tiers`: wasm available; the microvm and syscall tiers say they are Linux's).
8 9
9 10
## 0.5.2 (2026-10-29)
…
130 unchanged lines
modified crates/flow/src/runner.rs +40 −0
…
986 unchanged lines
987 987
                            claim.heads.first().map(|h| &h[..12]).unwrap_or("-")
988 988
                        );
989 989
                        crate::metrics::RUNNING.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
990 +
                        let _shown = Running::start(id, format!("{} #{} {}", claim.repo, claim.run_number, claim.job.name));
990 991
                        let finish = run_claim(home, hub, cfg, key, &claim, image_ms).unwrap_or_else(|e| Finish {
991 992
                            exit_code: None,
992 993
                            duration_ms: 0,
…
305 unchanged lines
1298 1299
    hub.download_build(offer, file)
1299 1300
}
1300 1301
1302 +
/// The jobs this runner is running now, for a host to show (the Android
1303 +
/// app's card and notification, oxygenhub-android#8): by job id,
1304 +
/// "owner/name #run job".
1305 +
static RUNNING_NOW: std::sync::Mutex<std::collections::BTreeMap<i64, String>> = std::sync::Mutex::new(std::collections::BTreeMap::new());
1306 +
1307 +
/// A job shown in [`running`] while this lives.
1308 +
struct Running(i64);
1309 +
1310 +
impl Running {
1311 +
    fn start(id: i64, what: String) -> Running {
1312 +
        RUNNING_NOW.lock().unwrap_or_else(|p| p.into_inner()).insert(id, what);
1313 +
        Running(id)
1314 +
    }
1315 +
}
1316 +
1317 +
impl Drop for Running {
1318 +
    fn drop(&mut self) {
1319 +
        RUNNING_NOW.lock().unwrap_or_else(|p| p.into_inner()).remove(&self.0);
1320 +
    }
1321 +
}
1322 +
1323 +
/// What this runner is running now: "owner/name #run job" for each job, in
1324 +
/// the order claimed.
1325 +
pub fn running() -> Vec<String> {
1326 +
    RUNNING_NOW.lock().unwrap_or_else(|p| p.into_inner()).values().cloned().collect()
1327 +
}
1328 +
1301 1329
/// Held while a job takes its cache disks and images its workspace (see
1302 1330
/// `run_claim`): one job at a time on the runner's disk and cache pool.
1303 1331
static PREPARE: std::sync::Mutex<()> = std::sync::Mutex::new(());
…
528 unchanged lines
1832 1860
1833 1861
#[cfg(test)]
1834 1862
mod tests {
1863 +
1864 +
    #[test]
1865 +
    fn running_jobs_show_while_they_run() {
1866 +
        let a = super::Running::start(-41, "andy/demo #7 test".into());
1867 +
        let b = super::Running::start(-40, "andy/demo #7 lint".into());
1868 +
        let now = super::running();
1869 +
        assert!(now.contains(&"andy/demo #7 test".to_string()) && now.contains(&"andy/demo #7 lint".to_string()));
1870 +
        drop(a);
1871 +
        assert!(!super::running().contains(&"andy/demo #7 test".to_string()));
1872 +
        drop(b);
1873 +
        assert!(!super::running().iter().any(|r| r.starts_with("andy/demo #7")));
1874 +
    }
1835 1875
1836 1876
    /// #98: register keeps a copy of the CA in the home, by absolute path,
1837 1877
    /// and keeping the home's own copy again is a no-op.
…
562 unchanged lines