Skip to main content

ActivityDispatcher

Struct ActivityDispatcher 

Source
pub struct ActivityDispatcher { /* private fields */ }
Expand description

Push dispatcher backed by the connected-worker registry.

Implementations§

Source§

impl ActivityDispatcher

Source

pub fn new(registry: ConnectedWorkerRegistry) -> Self

Build a dispatcher over the shared worker registry.

Source

pub fn with_heartbeat_tracker(self, heartbeat_tracker: HeartbeatTracker) -> Self

Share the deployment’s liveness tracker, so a dispatch this path places is counted against the worker’s advertised capacity exactly as a bridge-seam dispatch is.

Required for the capacity contract to hold on this path: the tracker’s in-flight map IS the count selection reads.

Source

pub fn with_lease_recorder(self, lease_recorder: LeaseRecorderSeam) -> Self

Share the lease-record seam, so an accepted delivery on this path is attributed through the same recorder (and counted on the same ledger) as one on the engine-seam bridge.

Source

pub fn with_delivery_gate(self, delivery_gate: DeliveryGate) -> Self

Share the deployment’s delivery gate, so a dispatch waiting on a blocking transport abandons promptly when the server begins draining.

Source

pub fn with_liminal_delivery( self, liminal_delivery: Arc<dyn WorkerTaskDelivery>, ) -> Self

Install the liminal delivery arm, so a liminal-registered worker selected by this dispatcher is SERVED over its own transport rather than deregistered for lacking a gRPC sender (#52).

Source

pub fn with_cluster_publisher( self, cluster_publisher: ClusterEventPublisher, ) -> Self

Share the deployment-global cluster-event publisher so a dispatch parked with no availability deadline on this leg is announced on the operator’s real-time channel, not only in the log (#266 T4).

Source

pub fn with_queue_service( self, declarations: QueueDeclarationSource, state: QueueServiceState, config: QueueServiceConfig, ) -> Self

Share the queue-service seams so a park on this path reaches the same GET /queues/unserved and describe surfaces the direct path feeds.

Source

pub fn with_drain_state(self, drain_state: DrainState) -> Self

Share the server drain gate.

Source

pub fn with_completion_fences(self, completion_fences: CompletionFences) -> Self

Share the completion-generation registry used by result ingestion.

Source

pub async fn dispatch( &self, activity: &ScheduledActivity, ) -> Result<(), ServerError>

Push a scheduled activity to a matching worker.

§Errors

Returns a typed dispatch error if no worker is available or the selected stream is closed; returns lock poison if registry access cannot be trusted.

Source

pub async fn dispatch_preferring( &self, activity: &ScheduledActivity, preferred: &BTreeSet<String>, ) -> Result<(), ServerError>

Dispatch activity preferring workers on one of the preferred node labels, spilling to ANY live worker when none of the preferred labels has a live worker (Control-Plane Phase 2, P2-P3 — the Prefer{L} soft spill).

This is consulted ONLY for an UNPINNED activity (activity.node == None): a per-activity authored pin always wins and is dispatched through Self::dispatch unchanged. The recorded row’s node is NEVER mutated — preference is a pure dispatch-time worker-selection optimization in this non-replayed path, exactly like the existing round-robin, so replay is untouched (CP-Phase-2 §2.4).

The prefer-then-spill tier sequence is derived ONCE, from the shared preferred_node_order. There is now only one walk to derive it for: since #52 R4 this dispatcher selects for BOTH transports and each chosen worker is served over the one it registered on, so “prefer labelled worker, spill to any” has a single meaning by construction rather than by two implementations agreeing:

Tier 1..N: for each preferred label (deterministic set order) try a NON-WAITING workers_for(node = Some(label)) and dispatch to the first live worker found. Tier N+1 (spill): if no preferred label has a live worker, fall back to Self::dispatch with the activity’s own (unpinned) node, so the wait-for-worker backstop and round-robin behave exactly as today. An empty preferred set is the spill case immediately.

§Errors

As Self::dispatch.

Source

pub async fn dispatch_requiring( &self, activity: &ScheduledActivity, required: &BTreeSet<String>, ) -> Result<(), ServerError>

Dispatch activity REQUIRING a worker whose advertised node is one of the required labels, WAITING when none is live and NEVER spilling to a node=None any-worker dispatch (Control-Plane Phase 2, P2-I1 — the Pinned{L} hard pin). This is the opposite of Self::dispatch_preferring: a Prefer set appends a None spill tier; a Pinned set has NO None tier and instead holds on the wait-for-worker backstop until an L-labelled worker registers.

Consulted ONLY for an UNPINNED activity (activity.node == None): a per-activity authored pin always wins and dispatches through Self::dispatch unchanged. The recorded row’s node is NEVER mutated — the required set is a pure dispatch-time worker-selection input in this non-replayed path, so replay is untouched (CP-Phase-2 §2.4).

Each retry tries every required label (deterministic [BTreeSet] order) via a NON-WAITING workers_for(node = Some(label)) and delivers to the first live worker found, preserving the round-robin exactly like Self::dispatch_to_node. When no required label has a live worker across the whole set, it awaits the WorkerArrival it subscribed to BEFORE walking the set and retries — the same isolation-stall a per-activity Some(N) pin already exhibits. An EMPTY required set can never be satisfied by any labelled worker, so it stalls (isolation > availability); the caller sets a non-empty Pinned{L} for a live pin.

§Errors

As Self::dispatch.

Trait Implementations§

Source§

impl Clone for ActivityDispatcher

Source§

fn clone(&self) -> ActivityDispatcher

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 ActivityDispatcher

Source§

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

Formats the value using the given formatter. 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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

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> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

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

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> IntoMaybeUndefined<T> for T

Source§

fn into_maybe_undefined(self) -> MaybeUndefined<T>

Converts this value into a three-state builder argument.
Source§

impl<T> IntoOption<T> for T

Source§

fn into_option(self) -> Option<T>

Converts this value into an optional builder argument.
Source§

impl<T> IntoRequest<T> for T

Source§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
Source§

impl<L> LayerExt<L> for L

Source§

fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>
where L: Layer<S>,

Applies the layer to a service and wraps it in Layered.
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
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.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more