soju/doc/architecture.md
Simon Ser ad2c142c36
Remove per-network ring buffer goroutines
Just dispatch from the user goroutine. This allows removes a lot of complexity.
2020-04-06 18:05:36 +02:00

34 lines
1.4 KiB
Markdown

# soju architecture
soju manages two types of connections:
- Upstream connections: soju maintains persistent connections to
user-configured IRC servers
- Downstream connections: soju accepts connections from IRC clients
On startup, soju will iterate over the list of networks stored in the database
and try to open an upstream connection for each network.
## Ring buffer
In order to correctly send history to each downstream client, soju maintains
for each network a single-producer multiple-consumer ring buffer. The network's
upstream connection produces messages and multiple downstream connections
consume these messages. Each downstream client may have a different cursor in
the history: for instance a client may be 10 messages late while another has
consumed all pending messages.
## Goroutines
Each type of connection has two dedicated goroutines: the first one reads
incoming messages, the second one writes outgoing messages.
Each user has a dedicated goroutine responsible for dispatching all messages.
It communicates via channels with the per-connection reader and writer
goroutines. This allows to keep the dispatching logic simple (by avoiding any
race condition or inconsistent state) and to rate-limit each user.
The user dispatcher goroutine receives from the `user.events` channel. Upstream
and downstream message handlers are called from this goroutine, thus they can
safely access both upstream and downstream state.