pub struct LiminalConnectionNotifier { /* private fields */ }Expand description
Connection-keyed ConnectionNotifier that turns liminal’s in-band worker
registration into a first-class ConnectedWorkerRegistry membership.
This is the SERVER half of LSUB-L2: when a worker connects with a
WireWorkerRegistration (the SDK’s connect_with_registration), liminal’s
connection process invokes on_worker_registered
with the connection’s beamr pid and the worker’s declared
(namespaces, task_queue, node, activity_types). The notifier builds a
WorkerDelivery::Liminal over the connection and inserts it into the
registry — the SAME registry entry, selected the SAME way, as a gRPC worker —
retiring the LSUB-1 out-of-band active_connection_pids() + hard-coded
registration hack.
§Lifetime of the registration guard
ConnectedWorkerRegistry::register_delivery returns a
WorkerRegistration guard whose drop deregisters the worker. The notifier
OWNS that guard keyed by pid (Mutex<HashMap<u64, WorkerRegistration>>), so
the registration lives exactly as long as the connection: it is inserted on
register and removed (dropped) on
on_worker_unregistered, which liminal fires
on connection close.
§Construction-order cycle (notifier <-> supervisor)
[Self::dispatch’s delivery] needs a ConnectionSupervisor handle to push
to the worker’s connection, but the supervisor is itself constructed WITH this
notifier (ConnectionSupervisor::with_services_and_notifier) — a cycle. The
notifier therefore holds the supervisor behind a OnceLock, populated
IMMEDIATELY after the supervisor is built via Self::bind_supervisor. The
OnceLock is never read before it is set in correct wiring (a worker can only
register after the listener — built after the supervisor and after
bind_supervisor — accepts its connection); if it somehow were, registration
is REJECTED with a typed error rather than panicking, so there is no
production unwrap/expect and no second always-None code path.
Implementations§
Source§impl LiminalConnectionNotifier
impl LiminalConnectionNotifier
Sourcepub fn new(registry: ConnectedWorkerRegistry) -> Self
pub fn new(registry: ConnectedWorkerRegistry) -> Self
Build a notifier that registers connecting workers into registry.
The supervisor handle is bound separately via Self::bind_supervisor
immediately after the supervisor is constructed, resolving the
notifier <-> supervisor construction cycle (see the type docs).
Sourcepub fn with_heartbeat_tracker(self, tracker: HeartbeatTracker) -> Self
pub fn with_heartbeat_tracker(self, tracker: HeartbeatTracker) -> Self
Install the shared per-task liveness tracker so a worker’s automatic
WorkerLivenessBeat publishes refresh the SAME in-flight entries the
bridge dispatcher tracks and the #176 sweeper expires.
MUST be wired on every boot that hosts the engine-seam bridge (the production composition does), or the sweeper would expire healthy liminal workers running activities longer than the heartbeat window. Without it (isolated tests that never bridge-dispatch) beats are consumed and dropped.
Sourcepub fn with_transcript_publisher(
self,
publisher: ActivityEventPublisher,
) -> Self
pub fn with_transcript_publisher( self, publisher: ActivityEventPublisher, ) -> Self
Install the transcript sequencer a worker’s observability publishes drain into (NOI-5b), capturing the CURRENT Tokio runtime handle to bridge the synchronous connection-process callback onto the async publish.
MUST be called from within a Tokio runtime (the server boot path is), so the
captured Handle can spawn the append+fan-out when a
worker publishes a transcript event over the reserved channel. Without this
builder the observability tap is a no-op (a plain, non-agent deployment).
§Panics
Panics if called outside a Tokio runtime — a construction-time wiring error in the server boot, never a runtime condition (the boot path always builds the notifier inside the server runtime).
Sourcepub fn with_intervention_capabilities(
self,
capabilities: InterventionCapabilities,
) -> Self
pub fn with_intervention_capabilities( self, capabilities: InterventionCapabilities, ) -> Self
Set the neutral intervention capability set every worker registering through this notifier advertises (NOI-6, item 4).
The composition root wires this from the harness’s advertised
AgentSession::capabilities() so a liminal-connected agent worker’s handle
carries the primitives its harness supports, which the intervention router
gates on. Without this builder the set is empty (observability-only), so a
plain activity worker advertises no controls. Pure builder addition, mirroring
the registry’s capability-carrying registration façade.
Sourcepub fn bind_supervisor(&self, supervisor: ConnectionSupervisor) -> bool
pub fn bind_supervisor(&self, supervisor: ConnectionSupervisor) -> bool
Bind the connection supervisor the notifier pushes through, immediately after it is constructed with this notifier.
Returns true when the supervisor was stored, false when it was already
bound (a second bind is a wiring bug and is ignored, never overwriting the
live handle). Call this exactly once, right after
ConnectionSupervisor::with_services_and_notifier.
Trait Implementations§
Source§impl ConnectionNotifier for LiminalConnectionNotifier
impl ConnectionNotifier for LiminalConnectionNotifier
Source§fn on_worker_registered(
&self,
pid: u64,
registration: &WireWorkerRegistration,
) -> Result<(), LiminalServerError>
fn on_worker_registered( &self, pid: u64, registration: &WireWorkerRegistration, ) -> Result<(), LiminalServerError>
pid. Read moreSource§fn on_worker_unregistered(&self, pid: u64)
fn on_worker_unregistered(&self, pid: u64)
pid — which had a stored
registration — closes, so the application can release the association. Read moreAuto Trait Implementations§
impl !Freeze for LiminalConnectionNotifier
impl !RefUnwindSafe for LiminalConnectionNotifier
impl !UnwindSafe for LiminalConnectionNotifier
impl Send for LiminalConnectionNotifier
impl Sync for LiminalConnectionNotifier
impl Unpin for LiminalConnectionNotifier
impl UnsafeUnpin for LiminalConnectionNotifier
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> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request