pub struct FiberBuilder { /* private fields */ }Expand description
Per-fiber op builder. Owns its own kernels. No locks, no synchronization, no contention.
Created via OpBuilder::create_fiber_builder() at fiber startup.
Every kernel here may be on any engine: the main kernel and the
per-op kernels run on the fiber engine where an image is available
(crate::fiber_engine) and on the interpreter otherwise. Each is
paired with the interpreter program it runs or was imaged from,
which shares its input and output indices: names resolve on the
program once, and the kernel is driven by index.
Implementations§
Source§impl FiberBuilder
impl FiberBuilder
Sourcepub fn new(parent: &ScopeKernel) -> Self
pub fn new(parent: &ScopeKernel) -> Self
Create a new fiber builder whose main kernel is the parent’s own image bound under the parent, on the parent’s engine.
Sourcepub fn with_image(
parent: &ScopeKernel,
image: Option<Arc<dyn KernelProgram>>,
) -> Self
pub fn with_image( parent: &ScopeKernel, image: Option<Arc<dyn KernelProgram>>, ) -> Self
Create a new fiber builder whose main kernel runs image — the
fiber engine’s image of parent’s program — bound under
parent; the parent’s own image when image is None.
Per-fiber state is fresh; cell handles are Arc-shared with the
parent so writes propagate to the workload-root through the
cascade.
Sourcepub fn with_scope(
parent: &ScopeKernel,
image: Option<Arc<dyn KernelProgram>>,
scope_values: Vec<(String, Value)>,
) -> Self
pub fn with_scope( parent: &ScopeKernel, image: Option<Arc<dyn KernelProgram>>, scope_values: Vec<(String, Value)>, ) -> Self
Self::with_image, binding scope_values into the main kernel
as it is built, before its consts initialize, and remembering
them for the stanza-boundary Self::reset_captures.
Sourcepub fn attach_dispenser_kernels(&mut self, dispensers: &[Arc<dyn OpDispenser>])
pub fn attach_dispenser_kernels(&mut self, dispensers: &[Arc<dyn OpDispenser>])
SRD-68 Push 3 — populate this fiber’s per-op kernel slots
from the activity’s dispenser registry. Walks each
dispenser, calls dispenser.canonical_kernel() to get the
dispenser-owned canonical kernel (when present), and binds a
per-fiber kernel of its program under this fiber’s main kernel.
Slot positions match the dispenser registry’s order so
cycle-time dispatch can index by template_idx. Dispensers
that return None (no GK needs) get a None slot —
ExecCtx::wires falls back to the NullWireSource baseline
for those cycles.
A per-op kernel is instantiated from its op-template module on
the fiber engine when the fiber has one for the canonical’s
program, carrying the module’s result: write-throughs; any
other canonical program runs on the interpreter.
Called once per fiber, right after spawn, before any cycles run. Idempotent: re-attaching with the same registry is a no-op since canonical kernels are stable across phase activation.
Sourcepub fn cycle_wires(&mut self, template_idx: usize) -> CycleWires<'_>
pub fn cycle_wires(&mut self, template_idx: usize) -> CycleWires<'_>
The cycle-time wire surface for the firing dispenser at
template_idx: its per-fiber kernel, or this fiber’s main
kernel when the dispenser exposes no canonical kernel (the
flattened path).
Sourcepub fn main_wires(&mut self) -> CycleWires<'_>
pub fn main_wires(&mut self) -> CycleWires<'_>
The cycle-time wire surface over this fiber’s main kernel.
Sourcepub fn per_op_kernel(&self, template_idx: usize) -> Option<&dyn Kernel>
pub fn per_op_kernel(&self, template_idx: usize) -> Option<&dyn Kernel>
Get the per-fiber kernel for the firing dispenser at
template_idx. Returns None when the dispenser exposes
no canonical kernel (adapters with no Polydat needs); callers
fall back to the NullWireSource baseline.
Sourcepub fn main_kernel(&self) -> &dyn Kernel
pub fn main_kernel(&self) -> &dyn Kernel
This fiber’s main kernel.
Sourcepub fn program(&self) -> &Arc<PolydatProgram> ⓘ
pub fn program(&self) -> &Arc<PolydatProgram> ⓘ
The interpreter program this fiber’s main kernel runs or was imaged from.
Sourcepub fn set_inputs(&mut self, coords: &[u64])
pub fn set_inputs(&mut self, coords: &[u64])
Set coordinates and begin a new evaluation scope.
Bounded by each kernel’s coordinate count: the slice is
truncated to the program’s declared coordinate count
before being written. A phase kernel with no
coordinates (e.g. all bindings are invariant within the
stanza, only externs declared) has coord_count = 0,
so this becomes a no-op rather than clobbering the
extern slots that follow.
SRD-13d Phase 9: the same coordinates are also written to
every per-op-template kernel that declares them as
coords. Each kernel binds its own input slot for cycle
(cascaded from parent) so per-cycle propagation is a
per-kernel set_inputs, not a chain walk.
Sourcepub fn set_source_item(&mut self, item: &SourceItem)
pub fn set_source_item(&mut self, item: &SourceItem)
Feed a source item into the fiber’s kernels.
Sets the ordinal as the coordinate input and injects field
projections into the appropriate input slots (e.g.
base__ordinal, base__vector). The ordinal write is
skipped by kernels whose programs declare no coordinates
(only externs and stanza-invariant bindings) rather than
clobbering an extern slot. Field projections always write by
name, so they’re safe regardless of coordinate count.
SRD-13d Phase 9: ordinal + fields propagate to every op-template kernel that declares matching slots.
Sourcepub fn reset_captures(&mut self)
pub fn reset_captures(&mut self)
Reset capture inputs to defaults. Called at stanza
boundaries to prevent capture leakage across stanzas.
Coordinates and cell-bound slots are not reset. Scope-bound
iter-var inputs (set by OpBuilder::create_fiber_builder)
are re-applied after the reset so the iteration’s bound
values survive the boundary.
Sourcepub fn invalidate_all(&mut self)
pub fn invalidate_all(&mut self)
Invalidate all state: every step, a side channel included, runs again when next pulled. Provides “clean slate” semantics.
Sourcepub fn capture(&mut self, name: &str, value: Value) -> bool
pub fn capture(&mut self, name: &str, value: Value) -> bool
Store a captured value into the main kernel’s input slot name.
Returns true when the slot exists and took the value, false
when the program has no such input or the value could not be
converted to its type (value dropped).
Sourcepub fn write_op_template_input_for_idx(
&mut self,
template_idx: usize,
name: &str,
value: Value,
) -> bool
pub fn write_op_template_input_for_idx( &mut self, template_idx: usize, name: &str, value: Value, ) -> bool
SRD-68 Push 5d: position-indexed write into the per-fiber
op-template kernel slot. Used by the cycle dispatch’s
post-execute capture flow to feed result-binding inputs
(body / count / ok and any captures) into the kernel
before Self::commit_op_template_write_throughs_for_idx
fans the computed values up through parent shared cells.
No-op returning false when (a) the op didn’t materialise a
kernel (flattened op-template), or (b) the kernel doesn’t
declare an input slot for name (the closure-binding economy
dropped it because the source doesn’t reference it), or (c)
the value could not be converted to the slot’s type.
Sourcepub fn commit_op_template_write_throughs_for_idx(
&mut self,
template_idx: usize,
) -> Result<(), String>
pub fn commit_op_template_write_throughs_for_idx( &mut self, template_idx: usize, ) -> Result<(), String>
SRD-68 Push 5d: position-indexed Rule 2 write-through commit.
Pulls every __write_<X> and stores its value through the
cell-bound input slot for <X>, propagating each result-
binding LHS value to the parent’s SharedCell (and from
there to any sibling phase that imports the same name).
No-op when the kernel carries no write-throughs (typical
for ops without result:).
Errors when a write-through violates cell type stability (scope_model.md §“Type stability”) — surfaced by the fiber loop as a phase-stopping workload bug (it is deterministic: every subsequent cycle would repeat it).
Sourcepub fn pull_all_op_template_outputs_for_idx(&mut self, template_idx: usize)
pub fn pull_all_op_template_outputs_for_idx(&mut self, template_idx: usize)
Per-cycle: pull the op-template kernel’s side-effecting
outputs at template_idx so side-effecting nodes (log_info
and friends) actually evaluate. Without this, captured wires
whose only consumer is a write-through are pulled by
commit_write_throughs, but captured wires that aren’t shared
with a parent never get pulled — their compute chain (including
any side-effecting nodes inside it) stays dormant, and the
diagnostic the workload asked for never fires.
Only outputs whose cone contains a Purity::SideChannel node are
pulled (the set is precomputed at attach time,
PolydatProgram::outputs_with_side_effects). A side-effect-free
output is not pulled here: re-evaluating it would do nothing,
and for a volatile metric reader (a metricsql_* / metric
objective binding) it would issue a live metrics query every
cycle. Such values are evaluated only when actually consumed.
No-op when the kernel has no side-effecting outputs.
Sourcepub fn resolve_pulls(&mut self, plan: &PullPlan) -> ResolvedPulls
pub fn resolve_pulls(&mut self, plan: &PullPlan) -> ResolvedPulls
Materialize a PullPlan against this fiber’s main kernel.
O(plan_len) on the hot path, no name hashing — the plan
holds pre-resolved indices.
This is the cycle-time read path used by every wrapper that
holds PullHandles registered into the corresponding
ScopeFixture at init (SRD 31 §“Pull plan vs bind plan”,
SRD 32 §“Init-Time Fixture and Consumer Self-Registration”).
Sourcepub fn resolve_pulls_for_idx(
&mut self,
template_idx: usize,
plan: &PullPlan,
) -> ResolvedPulls
pub fn resolve_pulls_for_idx( &mut self, template_idx: usize, plan: &PullPlan, ) -> ResolvedPulls
SRD-68 Push 5d resolve path — picks the right kernel for the
dispenser at template_idx and resolves the plan against it.
When a per-fiber op-template kernel was instanced for that
position (every adapter exposes canonical_kernel() so this is
the typical case), it is used; otherwise the plan resolves
against the fiber’s main kernel (the flattened op-template path).
Either way the plan is checked against the interpreter program
the kernel was imaged from, whose indices it holds.
Auto Trait Implementations§
impl !RefUnwindSafe for FiberBuilder
impl !UnwindSafe for FiberBuilder
impl Freeze for FiberBuilder
impl Send for FiberBuilder
impl Sync for FiberBuilder
impl Unpin for FiberBuilder
impl UnsafeUnpin for FiberBuilder
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more