Skip to main content

Module events

Module events 

Source
Expand description

The live channel: one WebSocket over which this process reports what its executions are doing.

It is an adapter and holds no execution logic. It subscribes to crate::execution::ExecutionStore, renders what arrives, and closes; every decision about what an execution is, what may happen to it and what an event means was already taken in crate::execution. That is what makes an audit trail, a notifier or a second protocol something that subscribes here rather than something that has to be threaded through the engine.

§The protocol

GET /events                                  every execution of this process, live
GET /events?execution=<id>                   one execution, its whole retained history, then live
GET /events?execution=<id>&after=<sequence>  the same, from a cursor: what a reconnect asks for
GET /events?execution=<a>&execution=<b>      several executions, each its history, then live

The subscription is the request target, so there is nothing to send and nothing to acknowledge: a reconnect is a new URL with the sequence the client last saw, and the server replays the gap before it goes live.

Sequences are dense per execution, so a connection that follows several executions keeps a cursor for each. The one after starts every one of those cursors: each execution named is replayed from the events after it, up to MAX_REPLAY each. A client that reconnects to several executions sends the lowest sequence it saw among them and drops, per execution, what it already holds; with one execution that is exactly the sequence it last saw, as it always was. What the server writes is one JSON document per text frame, each with a type and a data: either a crate::execution::ExecutionEvent, or one of the StreamMessage control messages below. A client that does not recognise a type must ignore that frame; that is what lets a variant be added without a version change.

The server pings on a heartbeat and never reads a frame. A client that goes away is noticed within LOOK where the server can ask the connection’s socket (the read deadline’s sweeper finds it, super::deadline), and otherwise when the next write fails, which the heartbeat guarantees happens; a client that sends anything is ignored, and the reason is in super::ws. Beside the ping, which is a control frame a browser never shows to a page, the same quiet interval writes a stream.heartbeat text frame, so a client can tell a quiet channel from a dead one.

A replay is paged until it is caught up: a cursor further behind than one page (MAX_REPLAY) receives every retained event after it, not the first page and then the live stream with the rest missing. An event whose frame would exceed ws::MAX_FRAME_BYTES is written with its unbounded value — a completed execution’s output, a created one’s input — replaced by a Withheld reference naming where the whole value is read, rather than refused and taken for a client that went away.

Structs§

Accepted
An accepted connection, before the socket is handed over.
Withheld
What an event carries in place of a value too large for one frame: why it was withheld, how large it is, and where the whole value is read.

Enums§

Scope
What a connection follows.
StreamMessage
A message about the stream itself, rather than about an execution.

Constants§

HEARTBEAT
How often the server pings a quiet connection.
LOOK
How often a quiet channel asks whether its client has hung up: the idle timer’s own tick, so a channel that closes is no longer counted as use by the next time the timer looks.
MAX_CONNECTIONS
How many live channels one process serves at once. Beyond it, a connection is refused with a reason rather than accepted and starved.
MAX_REPLAY
How many retained events one page of a replay reads, per execution a scoped subscription follows. The replay reads pages until it is caught up, so this bounds one read of the store, not the replay.
PATH
Where the live channel is mounted. Not under the capability prefix: it is not a capability, it declares no input or output schema, and it answers no JSON over HTTP.

Functions§

accept
Decide what a request to PATH means: an accepted connection, or the response to send instead.
open_connections
How many live channels are open right now, for the health and perf projections.