Skip to main content

ProducerCtx

Struct ProducerCtx 

Source
pub struct ProducerCtx<'a> { /* private fields */ }
Expand description

Context handed to a producer’s build closure on activation.

Provides:

  • Self::node_id / Self::core — identity + Core access for sink callbacks that re-enter Core.
  • Self::subscribe_to — subscribe to an upstream Core node; the resulting Subscription is auto-tracked under node_id in the binding’s producer storage and dropped on producer deactivation.

Implementations§

Source§

impl<'a> ProducerCtx<'a>

Source

pub fn new( node_id: NodeId, core: &'a dyn CoreFull, storage: &'a ProducerStorage, ) -> Self

Construct a new context for the binding’s invoke_fn dispatch to call build closures. Internal — bindings call this; user code receives the constructed ctx via the build closure’s arg.

D246 r5 / D245: takes &dyn CoreFull — the one object-safe Core facade Core hands the binding via graphrefly_core::BindingBoundary::invoke_fn_with_core. A concrete &Core unsized-coerces to &dyn CoreFull at the call site, so existing &Core-holding call sites pass it directly (ProducerCtx::new(node, &core, &storage)). ProducerCtx only needs subscribe/try_subscribe/register_*/emit/mailbox/ binding/*_or_defer — all on CoreFull — so no concrete Core / thread-local / stored back-reference is required.

Source

pub fn node_id(&self) -> NodeId

The producer node’s id.

Source

pub fn core(&self) -> &dyn CoreFull

The Core dispatcher, as the object-safe CoreFull facade (D246 r5 / D245). Build-closure-side only — valid only for the duration of the build call (the Core relocates; D231). Long-lived sinks must use Self::emitter instead. Carries everything a build closure uses (subscribe/try_subscribe/ register_*/emit/binding/*_or_defer) without naming the concrete cell type.

Source

pub fn emitter(&self) -> ProducerEmitter

Sink-side emit handle (D232-AMEND/A′). Cheap-Clone; capture it into spawned sink closures and call emit_or_defer/complete_or_defer/error_or_defer exactly as the old cloned-Core did — ops post to the Core-owned mailbox and are applied in-wave by the drain-to-quiescence loop.

Source

pub fn storage(&self) -> ProducerStorage

The binding’s per-producer state storage (S2b). Replaces binding.producer_storage() for build closures / spawned sinks that track their own upstream subscriptions or per-op state: under D231 the build closure no longer holds a Arc<dyn ProducerBinding> (only ctx’s borrowed &Core + &ProducerStorage), and a sink can’t reach ProducerBinding either. The returned ProducerStorage is Arc<Mutex<…>>'static + cheap-Clone, so it can be captured into long-lived sink closures (exactly how the old code captured binding.producer_storage().clone()).

Source

pub fn subscribe_to(&self, source: NodeId, sink: Sink) -> SubscribeOutcome

Subscribe sink to upstream source. The Subscription is auto-tracked under the producer’s node_id; on producer deactivation, the binding drops the storage entry, which drops the Subscription, which unsubscribes the sink.

Phase H+ STRICT (D115, 2026-05-10): uses try_subscribe to attempt the subscription. On partition order violation, the subscribe is deferred to wave-end via DeferredProducerOp::Callback. (S2c/D248 single-owner: the per-partition wave_owner ReentrantMutexes are deleted — there is no cross-thread interleaving wave to serialize — so the deferred callback simply runs owner-side at wave-end with no lock acquisition.)

R2.2.7.b (D118, 2026-05-10): if the upstream is non-resubscribable AND already terminated, try_subscribe returns Err(SubscribeError::TornDown). /qa F2 (2026-05-10): the rejection is now surfaced to the caller via SubscribeOutcome::Dead so the operator can apply its per-op dead-source semantics — pre-F2 the rejection was silently swallowed, leaving operators wedged (zip waiting on a queue that would never fill, concat stuck on a source that would never advance, etc.). See SubscribeOutcome::Dead for per-operator guidance.

Auto Trait Implementations§

§

impl<'a> Freeze for ProducerCtx<'a>

§

impl<'a> !RefUnwindSafe for ProducerCtx<'a>

§

impl<'a> !Send for ProducerCtx<'a>

§

impl<'a> !Sync for ProducerCtx<'a>

§

impl<'a> Unpin for ProducerCtx<'a>

§

impl<'a> UnsafeUnpin for ProducerCtx<'a>

§

impl<'a> !UnwindSafe for ProducerCtx<'a>

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> 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> Same for T

Source§

type Output = T

Should always be Self
Source§

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

Source§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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.