%%% title = "The Federation Side Bus" abbrev = "federation-side-bus" docName = "federation-side-bus" ipr = "none" workgroup = "Synapse"
[seriesInfo] name = "RFC" stream = "IETF" status = "informational" value = "federation-side-bus"
[pi] toc = "yes" topblock = "yes"
[[author]] initials = "A." surname = "Brown" fullname = "Amber Brown" organization = "New Vector"
[author.address]
email = "amberb@matrix.org"
%%%
.# Abstract
Proposal for the "Federation Side Bus" project. Proposed refactoring of federation transport code as well as externally communicating code. Proposed implementation of a message-bus style system for external communication. Proposed implementation of a prioritisation system covering different remote hosts based on liveliness as well as prioritisation of outgoing requests when experiencing backpressure.
{mainmatter}
On smaller machines, Synapse has problems when interacting with the federation in large rooms. Existing experience had pointed at state resolution being the performance killer, but further research with small homeservers has revealed the performance problems when communicating with many servers. The linear characteristics of having more servers in federation turns into a significant cliff in the realm of 200 or more servers on low-powered hardware, causing a "meltdown" and causing cascading failures as the server's non-responsiveness causes timeouts to clients and other servers.
The keywords MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, SHOULD NOT, RECOMMENDED, MAY, and OPTIONAL, when they appear in this document, are to be interpreted as described in [@!RFC2119].
Additionally, the key words "MIGHT", "COULD", "MAY WISH TO", "WOULD PROBABLY", "SHOULD CONSIDER", and "MUST (BUT WE KNOW YOU WON'T)" in this document are to interpreted as described in [@!RFC6919].
The keywords PDU, EDU, and QUERY in this document are to be interpreted as described in the Matrix Server to Server Specification [@!s2sapi].
EXTERNAL COMMUNICATION is defined as outgoing communication with another logical service, such as a web server or chat bot. Communication with the configured database, the filesystem, or with workers is not included in this definition.
FEDERATION REQUESTS are defined as any HTTP API call in the Matrix Server-to-Server specification, including PDUs, EDUs, or queries.
DEFERRED can mean either the literal Twisted Deferred, or a native coroutine that can await Deferreds. Which is used in the code depends on its use of native coroutines. APIs SHOULD try and implement native coroutines where possible, but they are described as "Deferreds" for brevity.
Synapse currently performs poorly under the following situations:
This can be attributed to the following fundamental issues:
In addition, the following issues make it more difficult to fix the above without a comprehensive approach:
atleastfornow.net
) can cause a poor user experience as misbehaving/timing out hosts can take up a slot that a well-behaved server or servers with users that are being actively communicated with could useFor large servers with workers, this can be mitigated somewhat by just throwing more hardware at the problem. For smaller ones, especially on constrained hardware (think ARM or shared hosting), this lack of rate limiting can cause hard spinning, swamping of resources, and total system failure.
Currently, Synapse talks over to other servers in the following places:
TODO: More detail?
Furthermore, profiles and room directory use the general query API.
The Federation Side Bus project remodels how Synapse approaches external communication. It draws naming parallels with the system bus design of personal computers and servers from the 1990s and 2000s, where the Front Side Bus was used to describe the communication interface between the CPU and its I/O systems (where the "back side bus" was instead between CPUs).
The core of the proposal is the definition of the "southbridge" (named for the I/O controller hub on a computer's FSB). The Southbridge is the only place where external communication is allowed to occur, and has a small but versatile interface for invoking said communication. This abstraction allows the Southbridge to be more intelligent about the use of network resources, as it can control all outbound data.
There are also additional abstractions and reworking of existing ones to make the internal logic more consistent. This is mostly focused on the reorganisation of the Federation code and the shifting of the Media Repo logic from being in REST servlets to handlers of their own. A reworking of ".well-known" resolution as well as hostname resolution in general is also proposed, with the end goal of increasing reliability and reducing the amount of code that needs to consider SRV/.well-known solving.
The Federation Side Bus will not alter Synapse's interaction with any of the Matrix standards, but will present the foundation for the future implementation of transports other than HTTP. HTTP/1.1 over TLS is targeted as the primary transport for Federation for this proposal, although HTTP/2.0 can be considered a "stretch goal" and desirable for its multiplexing and long-concurrent-connection qualities that would further reduce resource usage.
The Southbridge fully encapsulates all external communication (apart from DNS resolution). It consists of a number of queues, connection pools, and associated prioritisation and batching systems.
Zero-length queue that routes Federation requests through to the host ranker.
Tracks the performance of outbound requests and routes new requests through the different queues based on Matrix host.
A queue that enqueues events based on the Matrix host and requests a connection from the pool. When it has acquired a connection, it sends the events it has. If there is network pressure, the queue is responsible for giving up the connection based on a deadline. It is aware of federation semantics, and can intelligently collapse or discard EDUs or queries.
Holds HTTP requests and requests a connection from the connection pool to send them on. Used for general purpose queries (for example, .well-known lookups or URL previews).
Holds open HTTP connections and is responsible for establishing new ones. Operates on a callback basis with the queues. Hands over a connection to the queue requesting it, and is told when the queue is done with it. Assigns deadlines for the queues to follow (e.g. time spent processing) to ensure fairness.
The Federation Subsystem sees a number of changes, mostly revolving around refactoring the existing code and formalising interfaces.
Translates a Matrix homeserver hostname into "real" addresses that it can be contacted on. It is considered authoritive to the rest of the system.
Queues a Federation request in the Message Queue after attaching the "real address" information.
Shifting of Federation logic into more logically separated modules, such as separating by purpose (messages, queries, presence, etc) for clarity.
The functionality of the Media Repository REST APIs refactored into a handler.
Resolves domain names to DNS records. Although informally implemented in Synapse, this new subsystem would centralise a lot of the functionality of the various DNS resolvers used.
The implementation plan has three phases -- cleanup, plumbing, and optimising.
Cleanup focuses on shifting about existing code to fit the new model better. This involves implementing the Federation Resolver and cleaning up the media APIs.
Plumbing involves laying the groundwork for the changes. This involves writing a more controllable HTTP client, implementing the queueing and connection pool, and hooking it up to the existing Federation abstraction. The development of other queues and pools (like for URL previews, well-known lookups, etc) will also be done here, although can be done concurrently.
Optimising involves using these abstractions to allow Synapse to operate with network activity restrictions. This includes adding rate limiting, EDU collapsing,
This should all be moved out into a handler of its own, instead of existing in the REST APIs.
The base of the Federation Resolver can be implemented and placed in Synapse without much disruption.
Requirements:
Implement in the current MatrixFederationAgent and SimpleHTTPClient, with a basic connection pool.
The justification for this is that the current HTTP client libraries rely on controlling the connection itself, while we want to operate on a lower level and control the connection ourselves, and give it to the client instead. It represents an inversion of the concerns, which is why we have to provide this part ourselves.
This is not a large asking, as the h11 library implements all the logic (and is a much more solid HTTP state machine than Twisted's current HTTP Agent implementation). If it implements IAgent, we may wish to contribute this up to Twisted.
Requirements:
Questions:
Implement the Federation Queue API. This Queue is not used at this stage.
Requirements:
FederationTransactionResponse object
OutgoingEDU object
OutgoingPDU object
OutgoingQuery object
The base FederationQueue
An API to add a EDU/PDU onto the Queue.
An API to make a Federation query.
Questions:
Move the FederationSender code to use the Federation Queue.
Requirements:
A Queue that takes general HTTP requests and forwards them to a pool.
Move the URL previewer, well-known lookup to use the General Purpose Queue
Questions:
{backmatter}
<front>
<title>Federation API</title>
<author>
<organization>Matrix.org Foundation C.I.C.</organization>
</author>
<date year='2019'/>
</front>