• Stars
    star
    250
  • Rank 162,397 (Top 4 %)
  • Language
    Go
  • License
    Apache License 2.0
  • Created almost 2 years ago
  • Updated 2 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Proxy implementation of MSC3575's sync protocol.

Sliding Sync

Run a sliding sync proxy. An implementation of MSC3575.

Proxy version to MSC API specification

This describes which proxy versions implement which version of the API drafted in MSC3575. See https://github.com/matrix-org/sliding-sync/releases for the changes in the proxy itself.

As of v0.99.12, the proxy implements this version of the MSC with the following exceptions:

  • the limited flag is not set in responses.
  • Delta tokens are unsupported.

Usage

NOTE: The proxy works fine with Dendrite and Synapse, but it doesn't work well with Conduit due to spec violations in the state of a room in /sync. Running the proxy with Conduit will cause more expired connections (HTTP 400s) when room state changes, and log lines like WRN Accumulator.filterToNewTimelineEvents: seen the same event ID twice, ignoring.

Setup

Requires Postgres 13+.

First, you must create a Postgres database and secret:

$ createdb syncv3
$ echo -n "$(openssl rand -hex 32)" > .secret # this MUST remain the same throughout the lifetime of the database created above.

The Sliding Sync proxy requires some environment variables set to function. They are described when the proxy is run with missing variables.

Here is a short description of each, as of writing:

SYNCV3_SERVER     Required. The destination homeserver to talk to (CS API HTTPS URL) e.g 'https://matrix-client.matrix.org' (Supports unix socket: /path/to/socket)
SYNCV3_DB         Required. The postgres connection string: https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING
SYNCV3_SECRET     Required. A secret to use to encrypt access tokens. Must remain the same for the lifetime of the database.
SYNCV3_BINDADDR   Default: 0.0.0.0:8008. The interface and port to listen on. (Supports unix socket: /path/to/socket)
SYNCV3_TLS_CERT   Default: unset. Path to a certificate file to serve to HTTPS clients. Specifying this enables TLS on the bound address.
SYNCV3_TLS_KEY    Default: unset. Path to a key file for the certificate. Must be provided along with the certificate file.
SYNCV3_PPROF      Default: unset. The bind addr for pprof debugging e.g ':6060'. If not set, does not listen.
SYNCV3_PROM       Default: unset. The bind addr for Prometheus metrics, which will be accessible at /metrics at this address.
SYNCV3_OTLP_URL Default: unset. The OTLP HTTP URL to send spans to e.g https://localhost:4318 - if unset does not send OTLP traces.
SYNCV3_OTLP_USERNAME Default: unset. The OTLP username for Basic auth. If unset, does not send an Authorization header.
SYNCV3_OTLP_PASSWORD Default: unset. The OTLP password for Basic auth. If unset, does not send an Authorization header.
SYNCV3_SENTRY_DSN Default: unset. The Sentry DSN to report events to e.g https://[email protected]/123 - if unset does not send sentry events.
SYNCV3_LOG_LEVEL  Default: info. The level of verbosity for messages logged. Available values are trace, debug, info, warn, error and fatal
SYNCV3_MAX_DB_CONN Default: unset. Max database connections to use when communicating with postgres. Unset or 0 means no limit.

It is easiest to host the proxy on a separate hostname than the Matrix server, though it is possible to use the same hostname by forwarding the used endpoints.

In both cases, the path https://example.com/.well-known/matrix/client must return a JSON with at least the following contents:

{
    "m.homeserver": {
        "base_url": "https://example.com"
    },
    "org.matrix.msc3575.proxy": {
        "url": "https://syncv3.example.com"
    }
}

Same hostname

The following nginx configuration can be used to pass the required endpoints to the sync proxy, running on local port 8009 (so as to not conflict with Synapse):

location ~ ^/(client/|_matrix/client/unstable/org.matrix.msc3575/sync) {
    proxy_pass http://localhost:8009;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header Host $host;
}

location ~ ^(\/_matrix|\/_synapse\/client) {
    proxy_pass http://localhost:8008;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header Host $host;
}

location /.well-known/matrix/client {
    add_header Access-Control-Allow-Origin *;
}

Running

There are two ways to run the proxy:

  • Compiling from source:
$ go build ./cmd/syncv3
$ SYNCV3_SECRET=$(cat .secret) SYNCV3_SERVER="https://matrix-client.matrix.org" SYNCV3_DB="user=$(whoami) dbname=syncv3 sslmode=disable password='DATABASE_PASSWORD_HERE'" SYNCV3_BINDADDR=0.0.0.0:8008 ./syncv3
  • Using a Docker image:
docker run --rm -e "SYNCV3_SERVER=https://matrix-client.matrix.org" -e "SYNCV3_SECRET=$(cat .secret)" -e "SYNCV3_BINDADDR=:8008" -e "SYNCV3_DB=user=$(whoami) dbname=syncv3 sslmode=disable host=host.docker.internal password='DATABASE_PASSWORD_HERE'" -p 8008:8008 ghcr.io/matrix-org/sliding-sync:latest

Optionally also set SYNCV3_TLS_CERT=path/to/cert.pem and SYNCV3_TLS_KEY=path/to/key.pem to listen on HTTPS instead of HTTP. Make sure to tweak the SYNCV3_DB environment variable if the Postgres database isn't running on the host.

Regular users may now log in with their sliding-sync compatible Matrix client. If developing sliding-sync, a simple client is provided (although it is not included in the Docker image).

To use the stub client, visit http://localhost:8008/client/ (with trailing slash) and paste in the access_token for any account on SYNCV3_SERVER. Note that this will consume to-device messages for the device associated with that access token.

When you hit the Sync button nothing will happen initially, but you should see:

INF Poller: v2 poll loop started ip=::1 since= user_id=@kegan:matrix.org

Wait for the first initial v2 sync to be processed (this can take minutes!) and then v3 APIs will be responsive.

Note that some clients might require that your home server advertises support for sliding-sync in the .well-known/matrix/client endpoint; details are in the work-in-progress specification document.

Prometheus

To enable metrics, pass SYNCV3_PROM=:2112 to listen on that port and expose a scraping endpoint GET /metrics. If you want to hook this up to a prometheus, you can just define prometheus.yml:

global:
    scrape_interval: 30s
    scrape_timeout: 10s
scrape_configs:
    - job_name: ss
      static_configs:
       - targets: ["host.docker.internal:2112"]

then run Prometheus in a docker container:

docker run -p 9090:9090 -v /path/to/prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus

to play with the data, use PromLens and point it at http://localhost:9090:

docker run -p 8080:8080 prom/promlens

Useful queries include:

  • rate(sliding_sync_poller_num_payloads{job="ss"}[5m]) : This shows the payload rate from pollers to API processes, broken down by type. A stacked graph display is especially useful as the height then represents the total payload rate. This can be used to highlight abnormal incoming data, such as excessive payload rates. It can also be used to gauge how costly certain payload types are. In general, receipts and device data tend to be the most frequent background noise. A full list of payload types are defined in the pubsub directory.
  • sliding_sync_poller_num_pollers : Absolute count of the number of /sync v2 pollers over time. Useful either as a single value, or display over time. The higher this value, the more pressure is put on the upstream Homeserver.
  • sliding_sync_api_num_active_conns : Absolute count of the number of active sliding sync connections. Useful either as a single value, or display over time. The higher this value, the more pressure is put on the proxy API processes.
  • sum(increase(sliding_sync_poller_process_duration_secs_bucket[1m])) by (le) : Useful heatmap to show how long /sync v2 responses take to process. This can highlight database pressure as processing responses involves database writes and notifications over pubsub.
  • sum(increase(sliding_sync_api_process_duration_secs_bucket[1m])) by (le) : Useful heatmap to show how long sliding sync responses take to calculate, which excludes all long-polling requests. This can highlight slow sorting/database performance, as these requests should always be fast.

Profiling

To help debug performance issues, you can make the proxy listen for PPROF requests by passing SYNCV3_PPROF=:6060 to listen on :6060. To debug why a request is slow:

wget -O 'trace.pprof' 'http://localhost:6060/debug/pprof/trace?seconds=20'

Then perform the slow request within 20 seconds. Send trace.pprof to someone who will then run go tool trace trace.pprof and look at "User-defined Tasks" for slow HTTP requests.

To debug why the proxy is consuming lots of memory, run:

wget -O 'heap.pprof' 'http://localhost:6060/debug/pprof/heap'

Then send heap.pprof to someone who will then run go tool pprof heap.pprof and probably type something like top10:

(pprof) top10
Showing nodes accounting for 83.13MB, 100% of 83.13MB total
Showing top 10 nodes out of 82
      flat  flat%   sum%        cum   cum%
   43.01MB 51.74% 51.74%    43.01MB 51.74%  github.com/tidwall/gjson.ParseBytes
   31.85MB 38.31% 90.05%    31.85MB 38.31%  github.com/matrix-org/sliding-sync/sync3.(*JoinedRoomsTracker).Startup
       4MB  4.82% 94.87%        4MB  4.82%  runtime.allocm
    1.76MB  2.12% 96.99%     1.76MB  2.12%  compress/flate.NewWriter
    0.50MB  0.61% 97.59%        1MB  1.21%  github.com/matrix-org/sliding-sync/sync3.(*SortableRooms).Sort
    0.50MB   0.6% 98.20%     0.50MB   0.6%  runtime.malg
    0.50MB   0.6% 98.80%     0.50MB   0.6%  github.com/matrix-org/sliding-sync/sync3.(*InternalRequestLists).Room
    0.50MB   0.6% 99.40%     0.50MB   0.6%  github.com/matrix-org/sliding-sync/sync3.(*Dispatcher).notifyListeners
    0.50MB   0.6%   100%     0.50MB   0.6%  runtime.acquireSudog
         0     0%   100%     1.76MB  2.12%  bufio.(*Writer).Flush

To debug why the proxy is using 100% CPU, run:

wget -O 'profile.pprof' 'http://localhost:6060/debug/pprof/profile?seconds=10'

Then send profile.pprof to someone who will then run go tool pprof -http :5656 profile.pprof and typically view the flame graph: View -> Flame Graph.

Developers' cheat sheet

Sanity check everything builds:

go build ./cmd/syncv3
go list ./... | xargs -n1 go test -c -o /dev/null

Run all unit and integration tests:

go test -p 1 -count 1 $(go list ./... | grep -v tests-e2e) -timeout 120s

Run end-to-end tests:

# Will need to `docker login` to ghcr and pull the image.
docker run -d --rm -e "SYNAPSE_COMPLEMENT_DATABASE=sqlite" -e "SERVER_NAME=synapse" -p 8888:8008 ghcr.io/matrix-org/synapse-service:v1.94.0

export SYNCV3_SECRET=foobar
export SYNCV3_SERVER=http://localhost:8888
export SYNCV3_DB="user=$(whoami) dbname=syncv3_test sslmode=disable"

(go build ./cmd/syncv3 && dropdb syncv3_test && createdb syncv3_test && cd tests-e2e && ./run-tests.sh -count=1 .)

More Repositories

1

synapse

Synapse: Matrix homeserver written in Python/Twisted.
Python
11,791
star
2

dendrite

Dendrite is a second-generation Matrix homeserver written in Go!
Go
4,696
star
3

matrix-js-sdk

Matrix Client-Server SDK for JavaScript
TypeScript
1,505
star
4

matrix-rust-sdk

Matrix Client-Server SDK for Rust
Rust
1,151
star
5

matrix-react-sdk

Matrix SDK for React Javascript
TypeScript
1,095
star
6

matrix-spec-proposals

Proposals for changes to the matrix specification
889
star
7

matrix-appservice-discord

A bridge between Matrix and Discord.
TypeScript
803
star
8

matrix.to

A simple stateless privacy-protecting URL redirecting service for Matrix
JavaScript
766
star
9

thirdroom

Open, decentralised, immersive worlds built on Matrix
C
599
star
10

matrix-appservice-irc

Node.js IRC bridge for Matrix
TypeScript
457
star
11

matrix-ios-sdk

The Matrix SDK for iOS
Objective-C
433
star
12

pinecone

Peer-to-peer overlay routing for the Matrix ecosystem
Go
428
star
13

matrix.org

matrix.org public website
JavaScript
413
star
14

matrix-android-sdk

The Matrix SDK for Android - DEPRECATED
Java
376
star
15

mjolnir

A moderation tool for Matrix
TypeScript
325
star
16

go-neb

Extensible matrix bot written in Go
Go
281
star
17

pantalaimon

E2EE aware proxy daemon for matrix clients.
Python
279
star
18

matrix-appservice-slack

A Matrix <--> Slack bridge
TypeScript
271
star
19

gomatrix

A Golang Matrix client
Go
269
star
20

sydent

Sydent: Reference Matrix Identity Server
Python
259
star
21

matrix-python-sdk

Matrix Client-Server SDK for Python 2 and 3
Python
256
star
22

purple-matrix

Libpurple protocol plugin for matrix
C
224
star
23

matrix-ircd

An IRCd implementation backed by Matrix.
Rust
224
star
24

matrix-android-sdk2

Matrix SDK for Android, extracted from the Element Android application
Kotlin
189
star
25

matrix-spec

The Matrix protocol specification
HTML
188
star
26

matrix-hookshot

A bridge between Matrix and multiple project management services, such as GitHub, GitLab and JIRA.
TypeScript
185
star
27

vodozemac

An implementation of Olm and Megolm in pure Rust.
Rust
171
star
28

matrix-bifrost

General purpose bridging with a variety of backends including libpurple and xmpp.js
TypeScript
162
star
29

rust-synapse-compress-state

A tool to compress some state in a Synapse instance's database
Rust
147
star
30

matrix-appservice-bridge

Bridging infrastructure for Application Services
TypeScript
141
star
31

matrix-ios-kit

Reusable UI interfaces to ease building of Matrix client apps
Objective-C
128
star
32

sygnal

Sygnal: reference Push Gateway for Matrix
Python
128
star
33

matrix-authentication-service

OAuth2.0 + OpenID Provider for Matrix Homeservers
Rust
111
star
34

matrix-synapse-ldap3

An LDAP3 auth provider for Synapse
Python
107
star
35

cerulean

An experimental Matrix client for playing with freestyle public threaded conversations
JavaScript
103
star
36

waterfall

A cascading stream forwarding unit for scalable, distributed voice and video conferencing over Matrix
Go
98
star
37

synapse-s3-storage-provider

Synapse storage provider to fetch and store media in Amazon S3
Python
92
star
38

matrix-rich-text-editor

Matrix Rich Text Editor
Rust
92
star
39

meshsim

Matrix mesh simulator
Python
90
star
40

matrix-static

A static golang generated preview of public world readable Matrix rooms.
Go
87
star
41

seshat

A Matrix message database/indexer
Rust
86
star
42

matrix-viewer

View the history of public and world readable Matrix rooms
JavaScript
74
star
43

matrix-appservice-node

Matrix Application Service framework in Node.js
TypeScript
71
star
44

sytest

Black-box integration testing for Matrix homeservers
Perl
66
star
45

matrix-federation-tester

Tester for matrix federation written in golang.
Go
61
star
46

complement

Matrix compliance test suite
Go
61
star
47

docker-jitsi

Docker files for building images and running jitsi-meet in Docker containers
Lua
58
star
48

matrix-widget-api

JavaScript/TypeScript API for widgets & web clients to communicate
TypeScript
57
star
49

gomatrixserverlib

Go library for matrix federation.
Go
56
star
50

olm

An implementation of the Double Ratchet cryptographic ratchet in C++/C
54
star
51

Matrix-NEB

N E Bot: Generic bot for Matrix with plugin support
Python
49
star
52

rust-opa-wasm

Open Policy Agent WebAssembly Rust SDK
Rust
46
star
53

naffka

Single in-process implementation of the sarama golang kafka APIs
Go
45
star
54

matrix-ios-console

The sample Matrix client for iOS
Objective-C
45
star
55

conference-bot

The conductor for your orchestra^Wconference
TypeScript
44
star
56

gsoc

JavaScript
43
star
57

matrix-appservice-gitter

Matrix <-> Gitter bridge
JavaScript
40
star
58

coap-proxy

HTTP<->CoAP proxy
Go
39
star
59

matrix-appservice-tg

Matrix<->Telegram user-puppeting portal
JavaScript
37
star
60

dendron

Dendron was an experimental Matrix homeserver, succeeded by Dendrite.
Go
35
star
61

matrix-vr-demo

Matrix.org Virtual Reality Demo
JavaScript
31
star
62

python-canonicaljson

Canonical JSON
Python
31
star
63

bullettime

An experimental golang Matrix homeserver
Go
31
star
64

matrix-angular-sdk

JavaScript
28
star
65

matrix-rust-components-swift

Swift package providing components from the matrix-rust-sdk
Swift
27
star
66

rageshake

Bug report server
Go
27
star
67

matrix-android-console

Java
26
star
68

matrix-android-sdk2-sample

Example project for using the android sdk
Kotlin
26
star
69

fed-tester-ui

UI for the matrix federation tester (forked from https://git.lain.haus/f0x/fed-tester)
JavaScript
26
star
70

lb

MSC3079 Low Bandwidth library for servers and clients
Go
25
star
71

prosody-mod-auth-matrix-user-verification

Matrix user verification auth for Prosody
Lua
24
star
72

voip-tester

Tests VoIP
JavaScript
23
star
73

thirdroom-unity-exporter

C#
23
star
74

matrix-user-verification-service

Service to verify details of a user based on a Open ID token.
JavaScript
23
star
75

matrix-search

A generic search engine daemon
Go
22
star
76

tardis

Time Agnostic Room DAG Inspection Service
JavaScript
21
star
77

synapse-auto-accept-invite

Synapse module to automatically accept invites
Python
18
star
78

libp2p-proxy

A p2p transport shim for p2p matrix.
Go
18
star
79

patience

Full stack integration testing for Matrix clients and servers
TypeScript
18
star
80

matrix-sentry-webhooks

Sentry webhooks integration bot for Matrix.
JavaScript
17
star
81

matrix-appservice-verto

A Matrix <--> Verto bridge, designed for conferencing
JavaScript
16
star
82

go-sqlite3-js

Go SQL driver for sqlite3 in browser (sql.js) from go-wasm
Go
15
star
83

matrix-appservice-rocketchat

JavaScript
15
star
84

matrix-content-scanner

[DEPRECATED] A web service for scanning media hosted by a Matrix media repository. Replaced by https://github.com/vector-im/matrix-content-scanner-python
JavaScript
13
star
85

synapse-user-restrictions

This module allows restricting users from performing actions such as creating rooms or sending invites.
Python
13
star
86

docker-dehydrated

A docker image we use internally for managing certificates.
Shell
13
star
87

matrix-rust-components-kotlin

Kotlin
12
star
88

matrix-rust-sdk-crypto-wasm

Rust
12
star
89

matrix-websockets-proxy

Websockets wrapper for matrix.org homeservers
Go
12
star
90

panopticon

panopticon records usage metrics from homeservers
Go
11
star
91

matrix-files-sdk

JS/TS SDK for working with files and folders in Matrix
TypeScript
11
star
92

remember-this-rs

A simple Rust crate to cache data both in-memory and on disk
Rust
11
star
93

complement-crypto

Go
10
star
94

allchange

A multi-project changelog generator
TypeScript
10
star
95

python-unpaddedbase64

Unpadded Base64
Python
10
star
96

synapse-email-account-validity

Account validity plugin for Synapse using email
Python
10
star
97

matrixmon

A small end-to-end prober and Prometheus stats exporter for a Matrix homeserver
Perl
10
star
98

matrix-synapse-saml-mozilla

Mozilla flavour of a Synapse SAML mapping provider
Python
9
star
99

vodozemac-bindings

Language bindings for vodozemac
Rust
9
star
100

synapse-config-generator

A web based synapse config generator
JavaScript
9
star