pub struct PersistedAttempt {
pub id: AttemptId,
pub policy_id: PolicyId,
pub github_runner_id: Option<u64>,
pub state: AttemptState,
pub outcome: Option<AttemptOutcome>,
pub process_id: Option<u32>,
pub runtime_path: PathBuf,
pub workspace_kind: WorkspaceKind,
pub workspace_slot: Option<u16>,
pub created_at: Timestamp,
pub terminal_at: Option<Timestamp>,
pub last_state_change_at: Timestamp,
}Expand description
Every stored column of one attempt, named rather than positional.
Why this is a struct. RunnerAttempt::from_persisted took ten
positional arguments, and two of them — created_at and
last_state_change_at — are both Timestamp. Transposing them type-checked,
compiled, and silently reverted last_state_change_at to created_at, which
is precisely the bug that field exists to prevent: every recovery timeout
would then have measured from allocation rather than from the current state,
so a long-running busy attempt would be read as a stuck one. terminal_at
is a third Option<Timestamp> in the same list.
b2 maps database columns onto this type. With a struct that mapping is
checked by name at compile time; positionally it was checked by nothing.
That guarantee covers the Rust side of the mapping and no more. It is
the field names that the compiler checks, not the column names they are
read from: PersistedAttempt { created_at: row.get("last_state_change_at")?, … } compiles exactly as happily as the correct version, and reintroduces the
very transposition described above. b2 still owes a test that loads a row
whose columns hold distinguishable values and asserts each landed in the
field of the same name; this type does not supply one.
Construct it with a struct literal so every field is written down at the call
site — that is the whole point, and a builder or a Default would give the
omission back.
Fields§
§id: AttemptId§policy_id: PolicyId§github_runner_id: Option<u64>§state: AttemptState§outcome: Option<AttemptOutcome>§process_id: Option<u32>§runtime_path: PathBuf§workspace_kind: WorkspaceKindephemeral or persistent, stored beside the slot below.
workspace_slot: Option<u16>The leased slot: Some exactly when workspace_kind is persistent,
and positive. It is a raw u16 here rather than a NonZeroU16 so that
the 0 a hand-edited row can hold is refused by
AttemptWorkspace::from_persisted instead of being unrepresentable at
the column boundary and panicking somewhere else.
created_at: TimestampWhen the runtime directory was allocated. Never moves.
terminal_at: Option<Timestamp>Set when, and only when, the attempt concluded.
last_state_change_at: TimestampWhen the attempt entered its current state. Recovery timeouts run
from here, not from created_at.
Trait Implementations§
Source§impl Clone for PersistedAttempt
impl Clone for PersistedAttempt
Source§fn clone(&self) -> PersistedAttempt
fn clone(&self) -> PersistedAttempt
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more