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.
 |