Skip to main content

HarnessEngine

Struct HarnessEngine 

Source
pub struct HarnessEngine { /* private fields */ }

Implementations§

Source§

impl HarnessEngine

Source

pub fn new() -> Self

Source

pub fn task(&self, task_id: &HarnessTaskId) -> Option<&HarnessTaskV1>

Source

pub fn run(&self, run_id: &HarnessRunId) -> Option<&HarnessRunV1>

Source

pub fn grant(&self, grant_id: &SessionGrantId) -> Option<&SessionGrantV1>

Source

pub fn operation( &self, operation_id: &HarnessOperationId, ) -> Option<&HarnessOperationV1>

Source

pub fn execution_spec( &self, task_id: &HarnessTaskId, ) -> Option<&HarnessTaskExecutionSpecV1>

Source

pub fn execution_specs( &self, ) -> impl Iterator<Item = &HarnessTaskExecutionSpecV1>

Source

pub fn task_launch_issuance( &self, task_id: &HarnessTaskId, ) -> Option<&HarnessTaskLaunchIssuanceV1>

Source

pub fn task_execution_spec_v2( &self, task_id: &HarnessTaskId, ) -> Option<&HarnessTaskExecutionSpecV2>

Source

pub fn task_launch_issuances( &self, ) -> impl Iterator<Item = &HarnessTaskLaunchIssuanceV1>

Source

pub fn task_execution_specs_v2( &self, ) -> impl Iterator<Item = &HarnessTaskExecutionSpecV2>

Source

pub fn delivery( &self, delivery_ref: &HarnessDeliveryRef, ) -> Option<&HarnessDeliveryV1>

Source

pub fn continuation( &self, continuation_ref: &HarnessContinuationRef, ) -> Option<&HarnessContinuationV1>

Source

pub fn continuation_for_run( &self, run_id: &HarnessRunId, ) -> Option<&HarnessContinuationV1>

Source

pub fn delivery_for_run( &self, run_id: &HarnessRunId, ) -> Option<&HarnessDeliveryV1>

Source

pub fn tasks(&self) -> impl Iterator<Item = &HarnessTaskV1>

Source

pub fn runs(&self) -> impl Iterator<Item = &HarnessRunV1>

Source

pub fn grants(&self) -> impl Iterator<Item = &SessionGrantV1>

Source

pub fn operations(&self) -> impl Iterator<Item = &HarnessOperationV1>

Source

pub fn deliveries(&self) -> impl Iterator<Item = &HarnessDeliveryV1>

Source

pub fn scheduler_pending_dispatch( &self, ) -> Result<Option<(&HarnessTaskV1, &HarnessRunV1, &HarnessOperationV1)>, HarnessEngineError>

Source

pub fn scheduler_pending_dispatches( &self, ) -> Result<Vec<(&HarnessTaskV1, &HarnessRunV1, &HarnessOperationV1)>, HarnessEngineError>

Source

pub fn scheduler_pending_dispatches_for( &self, operation_ids: &BTreeSet<HarnessOperationId>, ) -> Result<Vec<(&HarnessTaskV1, &HarnessRunV1, &HarnessOperationV1)>, HarnessEngineError>

Source

pub fn scheduler_ready_task( &self, ) -> Result<Option<&HarnessTaskV1>, HarnessEngineError>

Finds the first Ready, dependency-satisfied task by walking every stored task in order – there is no index by state, so this genuinely scans. Refuses only once the walk itself has examined HARNESS_SCHEDULER_SCAN_MAX tasks without returning; an eligible task found earlier in the walk is returned regardless of how large the store has grown.

Source

pub fn scheduler_ready_task_by_id( &self, task_id: &HarnessTaskId, ) -> Result<Option<&HarnessTaskV1>, HarnessEngineError>

Looks up one task by id and checks its own eligibility. The cost is that task’s own dependencies and run_ids, never the size of the store, so this does not consult any store-wide scan bound.

Source

pub fn task_nonterminal_run_id( &self, task: &HarnessTaskV1, ) -> Result<Option<HarnessRunId>, HarnessEngineError>

Walks one task’s own run_ids looking for a run that has not reached a terminal lifecycle, returning its id – the run whose lifecycle projection owns the task’s own state for as long as this keeps returning Some (HarnessTaskMoveResultV1::TaskOwnedByLiveRun, D5: while a run is non-terminal, a caller-initiated move that would change its task’s state races the run’s own projection and never wins it cleanly, so it is refused by name instead, naming this run). The cost is that task’s own run_ids.len(), never the size of the store, so this does not consult any store-wide scan bound.

Source

pub fn task_has_nonterminal_run( &self, task: &HarnessTaskV1, ) -> Result<bool, HarnessEngineError>

Bare presence check built on task_nonterminal_run_id – most callers (the scheduler’s own admission checks, operator_cancel_task/ operator_retry_task) only need to know whether a nonterminal run exists, not which one.

Source

pub fn unmet_task_dependencies( &self, task: &HarnessTaskV1, ) -> Vec<HarnessTaskId>

The subset of task.dependencies that scheduler_task_is_eligible’s dependencies_done check would treat as unmet – a dependency id that does not resolve to a stored task, or one that resolves but has not reached HarnessTaskStateV1::Done. This never decides admission itself (that stays with scheduler_task_is_eligible, reached only through scheduler_ready_task/scheduler_ready_task_by_id); it exists so a caller that already knows a task was refused can name which specific dependency id it is still waiting on instead of reporting a bare ineligibility.

Source

pub fn restore_deliveries( self, deliveries: Vec<HarnessDeliveryV1>, ) -> Result<Self, HarnessEngineError>

Source

pub fn read_visibility( &self, grant_id: &SessionGrantId, ) -> Result<HarnessReadVisibilityV1, HarnessEngineError>

Source

pub fn checkpoint(&self) -> HarnessEngineCheckpointV1

Source

pub fn restore( checkpoint: HarnessEngineCheckpointV1, ) -> Result<Self, HarnessEngineError>

Source

pub fn prepare( &self, mutation: HarnessMutationV1, ) -> Result<PreparedHarnessMutation, HarnessEngineError>

Source

pub fn prepare_delivery( &self, delivery: HarnessDeliveryV1, ) -> Result<PreparedHarnessMutation, HarnessEngineError>

Source

pub fn prepare_continuation( &self, continuation: HarnessContinuationV1, ) -> Result<PreparedHarnessMutation, HarnessEngineError>

Source

pub fn prepare_scheduled_run_authorities( &self, operation_id: &HarnessOperationId, delivery: Option<HarnessDeliveryV1>, continuation: Option<HarnessContinuationV1>, ) -> Result<PreparedHarnessMutation, HarnessEngineError>

Source

pub fn prepare_continuation_export( &self, expected_revision: HarnessRevision, continuation: HarnessContinuationV1, ) -> Result<PreparedHarnessMutation, HarnessEngineError>

Source

pub fn prepare_continuation_export_begin( &self, expected_revision: HarnessRevision, continuation: HarnessContinuationV1, ) -> Result<PreparedHarnessMutation, HarnessEngineError>

Source

pub fn prepare_continuation_export_outcome_unknown( &self, expected_revision: HarnessRevision, continuation: HarnessContinuationV1, ) -> Result<PreparedHarnessMutation, HarnessEngineError>

Source

pub fn prepare_continuation_expiry( &self, expected_revision: HarnessRevision, continuation: HarnessContinuationV1, ) -> Result<PreparedHarnessMutation, HarnessEngineError>

Source

pub fn prepare_accepted_spawn_continuation_bind( &self, expected_run_revision: HarnessRevision, run: HarnessRunV1, expected_operation_revision: HarnessRevision, operation: HarnessOperationV1, expected_continuation_revision: HarnessRevision, continuation: HarnessContinuationV1, ) -> Result<PreparedHarnessMutation, HarnessEngineError>

Source

pub fn prepare_accepted_spawn_delivery_and_continuation_commit( &self, expected_run_revision: HarnessRevision, run: HarnessRunV1, expected_operation_revision: HarnessRevision, operation: HarnessOperationV1, expected_delivery_revision: HarnessRevision, delivery: HarnessDeliveryV1, expected_continuation_revision: HarnessRevision, continuation: HarnessContinuationV1, ) -> Result<PreparedHarnessMutation, HarnessEngineError>

Source

pub fn prepare_delivery_stage( &self, expected_revision: HarnessRevision, delivery: HarnessDeliveryV1, ) -> Result<PreparedHarnessMutation, HarnessEngineError>

Source

pub fn prepare_accepted_spawn_delivery_commit( &self, expected_run_revision: HarnessRevision, run: HarnessRunV1, expected_operation_revision: HarnessRevision, operation: HarnessOperationV1, expected_delivery_revision: HarnessRevision, delivery: HarnessDeliveryV1, ) -> Result<PreparedHarnessMutation, HarnessEngineError>

Source

pub fn prepare_operation_transition( &self, expected_revision: HarnessRevision, operation: HarnessOperationV1, ) -> Result<PreparedHarnessMutation, HarnessEngineError>

Source

pub fn prepare_run_operation_transition( &self, expected_run_revision: HarnessRevision, run: HarnessRunV1, expected_operation_revision: HarnessRevision, operation: HarnessOperationV1, ) -> Result<PreparedHarnessMutation, HarnessEngineError>

Source

pub fn prepare_run_event_commit( &self, operation: HarnessOperationV1, expected_run_revision: HarnessRevision, run: HarnessRunV1, expected_task_revision: HarnessRevision, task: HarnessTaskV1, ) -> Result<PreparedHarnessMutation, HarnessEngineError>

Atomically records one run lifecycle event and projects it onto its task. The event operation is inserted exactly once; it is not the run’s original CreateRun operation.

Source

pub fn prepare_run_incarnation_settlement( &self, operation: HarnessOperationV1, expected_run_revision: HarnessRevision, run: HarnessRunV1, expected_task_revision: HarnessRevision, task: HarnessTaskV1, ) -> Result<PreparedHarnessMutation, HarnessEngineError>

Atomically settles one Running/Waiting run to the retryable Failed lifecycle (HarnessFailureCategoryV1::TargetUnavailable, retryable: true), its task to Failed, and drops the run’s own binding: the node incarnation the binding named is gone, so there is nothing left to bind to and nothing further this run will ever report. OutcomeUnknown is deliberately not this event’s target – that lifecycle names “we never learned whether the DISPATCH worked” and ties to an originating operation that must itself be OutcomeUnknown (validate_run_operation_coherence); a run reaching this path already dispatched successfully and ran, so its originating CreateRun operation is Succeeded and always will be, making Failed (which validate_run_operation_coherence already accepts against a Succeeded originating operation, the same way it does for a rejected spawn) the coherent, truthful word for it. The caller (hatchery-harness-service’s runtime) is the sole authority for WHEN this is legitimate – this crate has no C2 client of its own and never decides the trigger, only records the settlement once the caller already knows the run’s bound incarnation is provably stale.

A dedicated function rather than a widening of prepare_run_event_commit: this settlement’s authority shape and its task-side sibling (validate_incarnation_settlement_task_projection) stay independent of that function’s, even though both land the run on Failed – see prepare_run_event_commit’s own doc comment. Same CAS/idempotent-replay discipline as that function otherwise.

Source

pub fn prepare_run_context_pack_record( &self, operation: HarnessOperationV1, expected_run_revision: HarnessRevision, run: HarnessRunV1, ) -> Result<PreparedHarnessMutation, HarnessEngineError>

Narrow, single-entity, terminal-lifecycle-exempt mutation that records a durable ContextPack receipt a run’s own session cleanly exported. Deliberately does not call validate_run_lifecycle_transition (that function rejects any mutation on a terminal run) and never touches task state. Idempotent on the exact same receipt (a lost reconcile race just replays); a second, different receipt is a hard conflict.

Source

pub fn prepare_run_git_facts_record( &self, operation: HarnessOperationV1, expected_run_revision: HarnessRevision, run: HarnessRunV1, ) -> Result<PreparedHarnessMutation, HarnessEngineError>

Narrow, single-entity, terminal-lifecycle-exempt mutation that records a durable, one-shot git-facts capture of a run’s workspace. Structural twin of prepare_run_context_pack_record; the only behavioral difference is that this fact is legal to write exactly once — validate_git_facts_recording treats any change to an already-Some git_facts as a hard conflict regardless of cause (the A3 design has no legitimate “second capture” scenario the way a context pack has a legitimate re-export).

Source

pub fn prepare_task_result_ref_record( &self, operation: HarnessOperationV1, expected_task_revision: HarnessRevision, task: HarnessTaskV1, ) -> Result<PreparedHarnessMutation, HarnessEngineError>

Genuinely new mutation (no A2 analog): grows one task’s result_refs index by exactly one entry, attributing the growth to the exact run whose already-committed result caused it. Never touches task.state — the index is a passive fact about a task’s runs, not a task-state transition, the same doctrine A2 held for run state. Idempotent on an already-present ref, or on a task already at HARNESS_RESULTS_MAX capacity: both replay cleanly rather than conflicting.

Source

pub fn prepare_dispatch_outcome_commit( &self, expected_run_revision: HarnessRevision, run: HarnessRunV1, expected_operation_revision: HarnessRevision, operation: HarnessOperationV1, expected_task_revision: HarnessRevision, task: HarnessTaskV1, ) -> Result<PreparedHarnessMutation, HarnessEngineError>

Atomically records the categorical result of one leased CreateRun dispatch. Accepted outcomes use the authoritative spawn-proof seams.

Source

pub fn accept(&mut self, prepared: PreparedHarnessMutation)

Source

pub fn task_subtree( &self, root: &HarnessTaskId, depth_bound: u16, ) -> BTreeSet<HarnessTaskId>

The bounded set of task ids reachable from root by walking parent_task_id downward – root itself is included. Mirrors visible_runs_for_scope’s own Descendants shape (above) and its HARNESS_CHILD_DEPTH_MAX-class bound, just walked over the task graph’s own parent link instead of the run graph’s, and over depth_bound rather than a fixed constant so a caller can choose how deep this particular subtree check reaches. Unlike visible_runs_for_scope, hitting the bound does not fail closed with an error: this is a query, not an authorization decision by itself, and the direction is safe either way it is used for one – a task past the cut is simply absent from the returned set, which is exactly the answer a caller checking subtree membership wants for anything it cannot prove is inside (D5, Slice D: ParentOutsideOwnSubtree / TaskOutsideOwnSubtree).

Source

pub fn task_is_strict_descendant( &self, task: &HarnessTaskId, root: &HarnessTaskId, ) -> bool

Whether task is a strict (non-self) descendant of root – task_subtree(root, HARNESS_CHILD_DEPTH_MAX) minus root itself, the same depth fence the run graph’s own Descendants scope uses.

Source

pub fn task_child_count(&self, root: &HarnessTaskId) -> u64

The number of tasks parented directly under root right now – SessionContextV1::child_task_count’s own live observation, backing g4a_context_get. Recomputed by scanning self.tasks on every call, never a stored counter denormalised onto the task record (the owner’s ruling behind that field’s own doc comment: detect a session’s children, never cap them). Carries no upper bound of its own – a task can parent arbitrarily many children and this simply reports how many exist.

Source

pub fn task_subtree_depth(&self, root: &HarnessTaskId) -> u64

The depth of the deepest chain of tasks parented (transitively) under root right now – SessionContextV1::child_task_subtree_ depth’s own live observation: 0 when root has no children, 1 when it has children but none of those have children of their own, and so on. Walks parent_task_id downward the same way task_subtree does, but returns the depth actually reached instead of the set of ids, and – deliberately, unlike task_subtree – is not bounded by HARNESS_CHILD_DEPTH_MAX or any other ceiling: termination comes from self.tasks being finite (each pass either inserts at least one task new to visible or the loop stops, and visible can never hold more entries than self.tasks does), backed by validate_task_cycles keeping the task graph a forest on every mutation, not from a policy bound.

Source

pub fn own_task_of_run(&self, run_id: &HarnessRunId) -> Option<HarnessTaskId>

The task a run’s own grant governs – engine.run(run_id)?.task_id, named so a caller deciding “is this the caller’s own task” (HarnessTaskMoveResultV1::TaskIsOwn, D5) reads its intent rather than reaching into HarnessRunV1 directly.

Source

pub fn operations_for_task( &self, task_id: &HarnessTaskId, limit: usize, ) -> Vec<&HarnessOperationV1>

Every persisted HarnessOperationV1 naming task_id, newest first (created_at_unix_ms descending, ties broken by operation_id descending so the order is deterministic), bounded by limit – HarnessOperationV1.actor is stored today but had no read surface; this lets the service render an operator-side ledger with the raw actor for a given task.

Trait Implementations§

Source§

impl Clone for HarnessEngine

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for HarnessEngine

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for HarnessEngine

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl Eq for HarnessEngine

Source§

impl PartialEq for HarnessEngine

Manual, deliberately narrower than derive: equality is about the durable task/run/operation/grant/… graph this engine carries, never about mutation_generation or visibility_graph_cache, which are a write-mutation counter and a read cache respectively – process-local bookkeeping, not part of what makes two engines the same durable state. Without this, two engines holding identical data could compare unequal purely because one of them had served a read_visibility call and the other had not.

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.