Glimesh / janus-ftl-plugin

A plugin for the Janus WebRTC gateway to enable relaying of audio/video streams utilizing Mixer's FTL (Faster-Than-Light) protocol.
https://hayden.fyi/posts/2020-08-03-Faster-Than-Light-protocol-engineering-notes.html
GNU Affero General Public License v3.0
44 stars 11 forks source link

📬 FtlServer event queue model #102

Closed haydenmc closed 3 years ago

haydenmc commented 3 years ago

This change introduces a single-thread event queue model for FtlServer in order to minimize issues with deadlocks and out-of-order processing for sequential events.

FtlServer now contains definitions for 11 events that can be processed:

enum class FtlServerEventKind
{
    Unknown = 0,
    StopStream,                 // Request to stop a specific Channel / Stream ID
    NewControlConnection,       // ConnectionListener has produced a ConnectionTransport
    ControlConnectionClosed,    // FtlControlConnection has closed
    ControlRequestHmacKey,      // Control connection requests HMAC key
    ControlHmacKeyFound,        // HMAC key has been provided for a Control connection
    ControlRequestMediaPort,    // Control connection requests media port
    TerminateControlConnection, // Terminate and remove a Control connection
    StreamIdAssigned,           // StreamStartedCallback has returned a Stream ID
    StreamStarted,              // FtlStream has started successfully
    StreamStartFailed,          // FtlStream has failed to start
    StreamClosed,               // FtlStream has closed
};

Each event has an event payload that derives from FtlServer::FtlServerEvent.

When FtlServer is constructed, a jthread is initialized to process event queue events. When FtlServer is destructed, the stop_token is set on the jthread, stopping the event queue, and the jthread is joined.

Any public method exposed by FtlServer will enqueue an event in the queue to ensure events are processed in the intended order, and to avoid blocking the caller.

Similarly, any outgoing call will be processed on a new jthread via dispatchAsyncCall to avoid blocking the event queue. These threads will be tracked by FtlServer and joined on destruction of the class or when they finish their task. Return values will be enqueued as a task in the event queue for further processing.