webstation-broker
DeveloperPython referenceoutbox

outbox.Outbox

Queue a room connection's outbound messages and send them from one task.

Queue a room connection's outbound messages and send them from one task.

The drain task starts on the first queued message, so an outbox can be built before the event loop that serves the connection is known.

Attributes

attribute_websocket
= websocket
attributelabel
= label

The member's display name, for log lines only.

attribute_on_video_gap
= on_video_gap
attribute_jsoncollections.deque[dict[str, Any]]
= collections.deque()
attribute_audiocollections.deque[_Queued]
= collections.deque()
attribute_videocollections.deque[_Queued]
= collections.deque()
attribute_media_bytes
= 0
attribute_gapsset[bytes]
= set()
attribute_wake
= asyncio.Event()
attribute_idle
= asyncio.Event()
attribute_taskOptional[asyncio.Task[None]]
= None
attribute_closerOptional[asyncio.Task[None]]
= None
attribute_closed
= False
attributeabandoned
= asyncio.Event()

Set once the recipient is given up on as stuck.

attributedropped_video
= 0

Video frames discarded for this recipient.

attributedropped_audio
= 0

Audio frames discarded for this recipient.

Functions

func__init__(self, websocket, label, on_video_gap=None) -> None

Wrap a room connection's socket.

paramself
paramwebsocketWebSocket

The accepted room socket the messages go out on.

paramlabelstr

The member's display name, for log lines only.

paramon_video_gapOptional[Callable[[bytes], None]]
= None

Called with a sender's media id each time this recipient drops one of its video frames, until a keyframe gets through.

Returns

None
funcsend_json(self, payload) -> None

Queue a JSON message; it is never dropped while the connection lives.

paramself
parampayloaddict[str, Any]

The JSON-serializable message, normally carrying a type key.

Returns

None
funcsend_media(self, frame) -> None

Queue a media frame in its lane; it goes out unless it grows stale first.

paramself
paramframebytes

The stamped frame in the room's binary wire format.

Returns

None
funcflush(self, timeout) -> bool

Wait for everything queued so far to be sent or dropped.

paramself
paramtimeoutfloat

Seconds to wait at most.

Returns

bool

True if the queue emptied in time, False if it did not or the

funcaclose(self) -> None

Stop the drain task and discard anything still queued.

Called once the connection is over. It does not close the socket itself, and abandons a laggard close still under way, since the handler returning drops the connection anyway. Logs how many frames this recipient lost, if any.

paramself

Returns

None
func_clear(self) -> None

Drop everything queued and mark the outbox idle.

paramself

Returns

None
func_kick(self) -> None

Mark the outbox busy and make sure its drain task is running.

paramself

Returns

None
func_shut(self) -> None

Give up on a stuck recipient: drop its queue, stop its drain, and close it in the background.

paramself

Returns

None
func_close_socket(self) -> None

Close the socket with LAGGARD_CLOSE_CODE, giving up after CLOSE_WAIT.

paramself

Returns

None
func_drop_video(self, frame) -> None

Count a dropped video frame and wait for its sender's next keyframe.

Asks for that keyframe on every drop, not just the first: the request is rate-limited upstream, and a keyframe that arrives stale is lost too.

paramself
paramframebytes

The video frame being dropped.

Returns

None
func_evict_oldest(self) -> bool

Drop the oldest droppable frame to get back under the byte backstop.

Video goes first, since audio is the smaller and the more useful to keep; a video config message is never evicted.

paramself

Returns

bool

True if a frame was dropped, False if nothing droppable was queued.

func_next_media(self) -> Optional[bytes]

Take the next media frame worth sending, dropping stale and undecodable ones.

paramself

Returns

typing.Optional

The frame to send, or None once both media lanes are empty.

func_drain(self) -> None

Send queued messages, JSON then audio then video, until the outbox is closed.

paramself

Returns

None

On this page