Skip to main content

solti_runner/
id.rs

1//! # Run identifier generation.
2//!
3//! [`RunId`] is a human-readable task name for taskvisor, formatted as `{runner}-{slot}-{seq}`.
4//! The sequence is process-global and monotonically increasing (starts at 1).
5//!
6//! See [`Runner::build_run_id`](crate::Runner::build_run_id) for the default id builder.
7
8use std::sync::atomic::{AtomicU64, Ordering};
9
10/// Global monotonically increasing sequence for run identifiers.
11///
12/// Local to the current agent process.
13static RUN_SEQ: AtomicU64 = AtomicU64::new(1);
14
15/// Returns next numeric sequence value.
16fn next_seq() -> u64 {
17    RUN_SEQ.fetch_add(1, Ordering::Relaxed)
18}
19
20/// Result of [`make_run_id`]: a human-readable run id and the raw sequence number.
21#[derive(Debug, Clone, PartialEq, Eq)]
22pub struct RunId {
23    name: String,
24    seq: u64,
25}
26
27impl RunId {
28    /// Human-readable id used as task name for taskvisor.
29    ///
30    /// Format: `{runner}-{slot}-{seq}`.
31    #[inline]
32    pub fn name(&self) -> &str {
33        &self.name
34    }
35
36    /// Raw sequence number (monotonically increasing per process).
37    #[inline]
38    pub fn seq(&self) -> u64 {
39        self.seq
40    }
41
42    /// Consume and return the name as an owned `String`.
43    #[inline]
44    pub fn into_name(self) -> String {
45        self.name
46    }
47}
48
49/// Build a human-readable run id used as task name for taskvisor.
50///
51/// Format: `{runner}-{slot}-{seq}`.
52/// - `runner` - Runner::name()
53/// - `slot`   - TaskSpec.slot
54/// - `seq`    - per-process decimal sequence
55///
56/// Returns both the formatted name and the raw sequence number,
57/// so callers that need the seq (e.g. for cgroup naming) don't
58/// have to parse it back out of the string.
59pub fn make_run_id(runner_name: &str, slot: &str) -> RunId {
60    let seq = next_seq();
61    RunId {
62        name: format!("{runner_name}-{slot}-{seq}"),
63        seq,
64    }
65}