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}