pub struct RunContext<'a> {
pub catalog: &'a NodeCatalog,
pub cache: &'a dyn CacheStore,
pub events: &'a Arc<EventBus>,
pub run_id: &'a str,
pub graph_info: GraphInfo,
pub seed: Option<i64>,
pub driver: Option<EffectDriver>,
}Expand description
Everything a runner needs besides the plan and the data.
A struct rather than six more parameters, and one of them is the point:
graph_info. Both runner methods used to build
GraphInfo::for_linear(plan.node_ids()) — chaining the plan’s nodes in
flattened order as if every graph were a chain. On a diamond that is
simply wrong: GraphSession::forward on a → {b, c} → d answered with
d(c(...)), d never seeing b and a never seeing the input.
The caller supplies the real topology now. A caller that genuinely has
only a plan can still pass GraphInfo::for_linear, but it has to say so.
Fields§
§catalog: &'a NodeCatalogImplementations and trained states for every node in the plan.
cache: &'a dyn CacheStoreOutput cache consulted and filled by run_node.
events: &'a Arc<EventBus>Bus the run emits its node events on.
run_id: &'a strTags every node event of this run — callers that emit a
RunStarted/RunCompleted bracket pass the same id so readers can
group a run’s events.
graph_info: GraphInfoThe real topology for input resolution — the reason this struct exists; see the type docs.
seed: Option<i64>The run’s experiment seed, folded into every cache key.
Without it two seeds share a state cache line, so the second one trains on the first one’s recorded state and the sweep measures one seed N times. Only the Python fit path used to salt.
driver: Option<EffectDriver>Performs and journals step effects.
Needed only when the plan contains a step. It lives here rather than being built inside the runner because a driver carries the journal — which is what makes a resumed run replay instead of re-calling a model — and only the caller knows where that journal lives.
Implementations§
Source§impl<'a> RunContext<'a>
impl<'a> RunContext<'a>
Sourcepub fn new(
catalog: &'a NodeCatalog,
cache: &'a dyn CacheStore,
events: &'a Arc<EventBus>,
run_id: &'a str,
graph_info: GraphInfo,
) -> Self
pub fn new( catalog: &'a NodeCatalog, cache: &'a dyn CacheStore, events: &'a Arc<EventBus>, run_id: &'a str, graph_info: GraphInfo, ) -> Self
A context over the real topology; use Self::linear only when a
plan is genuinely all you have.
Sourcepub fn with_driver(self, driver: EffectDriver) -> Self
pub fn with_driver(self, driver: EffectDriver) -> Self
Register the effect driver a plan containing steps needs.
The driver should already carry its catalog
(crate::effects::EffectDriver::with_catalog) if a step may fan
out dynamically — the same rule as
crate::executor::Context::with_driver, so the two entry points
cannot drift apart on who attaches it.
Sourcepub fn linear(
catalog: &'a NodeCatalog,
cache: &'a dyn CacheStore,
events: &'a Arc<EventBus>,
run_id: &'a str,
plan: &ExecutionPlan,
) -> Self
pub fn linear( catalog: &'a NodeCatalog, cache: &'a dyn CacheStore, events: &'a Arc<EventBus>, run_id: &'a str, plan: &ExecutionPlan, ) -> Self
For a caller that has only a plan: treat it as a chain.
Correct for a linear pipeline and a fabrication for anything else, which is why it is spelled out at the call site rather than being what you get by default.