mirror of
https://mau.dev/maunium/synapse.git
synced 2024-11-09 11:32:01 +01:00
82 lines
2.8 KiB
Markdown
82 lines
2.8 KiB
Markdown
|
> **Warning**
|
||
|
> These architecture notes are spectacularly old, and date back
|
||
|
> to when Synapse was just federation code in isolation. This should be
|
||
|
> merged into the main spec.
|
||
|
|
||
|
# Server to Server
|
||
|
|
||
|
## Server to Server Stack
|
||
|
|
||
|
To use the server to server stack, home servers should only need to
|
||
|
interact with the Messaging layer.
|
||
|
|
||
|
The server to server side of things is designed into 4 distinct layers:
|
||
|
|
||
|
1. Messaging Layer
|
||
|
2. Pdu Layer
|
||
|
3. Transaction Layer
|
||
|
4. Transport Layer
|
||
|
|
||
|
Where the bottom (the transport layer) is what talks to the internet via
|
||
|
HTTP, and the top (the messaging layer) talks to the rest of the Home
|
||
|
Server with a domain specific API.
|
||
|
|
||
|
1. **Messaging Layer**
|
||
|
|
||
|
This is what the rest of the Home Server hits to send messages, join rooms,
|
||
|
etc. It also allows you to register callbacks for when it get's notified by
|
||
|
lower levels that e.g. a new message has been received.
|
||
|
|
||
|
It is responsible for serializing requests to send to the data
|
||
|
layer, and to parse requests received from the data layer.
|
||
|
|
||
|
2. **PDU Layer**
|
||
|
|
||
|
This layer handles:
|
||
|
|
||
|
- duplicate `pdu_id`'s - i.e., it makes sure we ignore them.
|
||
|
- responding to requests for a given `pdu_id`
|
||
|
- responding to requests for all metadata for a given context (i.e. room)
|
||
|
- handling incoming backfill requests
|
||
|
|
||
|
So it has to parse incoming messages to discover which are metadata and
|
||
|
which aren't, and has to correctly clobber existing metadata where
|
||
|
appropriate.
|
||
|
|
||
|
For incoming PDUs, it has to check the PDUs it references to see
|
||
|
if we have missed any. If we have go and ask someone (another
|
||
|
home server) for it.
|
||
|
|
||
|
3. **Transaction Layer**
|
||
|
|
||
|
This layer makes incoming requests idempotent. i.e., it stores
|
||
|
which transaction id's we have seen and what our response were.
|
||
|
If we have already seen a message with the given transaction id,
|
||
|
we do not notify higher levels but simply respond with the
|
||
|
previous response.
|
||
|
|
||
|
`transaction_id` is from "`GET /send/<tx_id>/`"
|
||
|
|
||
|
It's also responsible for batching PDUs into single transaction for
|
||
|
sending to remote destinations, so that we only ever have one
|
||
|
transaction in flight to a given destination at any one time.
|
||
|
|
||
|
This is also responsible for answering requests for things after a
|
||
|
given set of transactions, i.e., ask for everything after 'ver' X.
|
||
|
|
||
|
4. **Transport Layer**
|
||
|
|
||
|
This is responsible for starting a HTTP server and hitting the
|
||
|
correct callbacks on the Transaction layer, as well as sending
|
||
|
both data and requests for data.
|
||
|
|
||
|
## Persistence
|
||
|
|
||
|
We persist things in a single sqlite3 database. All database queries get
|
||
|
run on a separate, dedicated thread. This that we only ever have one
|
||
|
query running at a time, making it a lot easier to do things in a safe
|
||
|
manner.
|
||
|
|
||
|
The queries are located in the `synapse.persistence.transactions` module,
|
||
|
and the table information in the `synapse.persistence.tables` module.
|