1
0

Compare commits

..

42 Commits

Author SHA1 Message Date
Eric Eastwood
1c51b74e2d Merge branch 'develop' into madlittlemods/hs-specific-metrics
Conflicts:
	synapse/metrics/__init__.py
2025-06-20 11:24:57 -05:00
Eric Eastwood
ec16224828 Remove unrelated comment from reviewing another PR
From my review of https://github.com/element-hq/synapse/pull/18416
2025-06-13 16:37:02 -05:00
Eric Eastwood
00140fcc99 Merge branch 'develop' into madlittlemods/hs-specific-metrics
Conflicts:
	docs/usage/configuration/config_documentation.md
	synapse/module_api/callbacks/spamchecker_callbacks.py
2025-06-11 16:37:39 -05:00
Eric Eastwood
6e49db78ce Revert "Reapply "WIP: @cached progress""
This reverts commit 827b78554f.
2025-05-21 13:13:10 -05:00
Eric Eastwood
d4d59a49b3 Reapply "Reapply "Revert LruCache CacheManager changes for now""
This reverts commit e36c6f7803.
2025-05-21 13:13:03 -05:00
Eric Eastwood
5f5b3496f9 Reapply "Fixup after LruCache changes revert"
This reverts commit 962d5cecbf.
2025-05-21 13:12:57 -05:00
Eric Eastwood
e433a680a1 Revert "WIP: Idea on managing caches"
This reverts commit c5bbff9584.
2025-05-21 13:12:32 -05:00
Eric Eastwood
c5bbff9584 WIP: Idea on managing caches 2025-05-21 13:11:47 -05:00
Eric Eastwood
6a11964228 Interim comment 2025-05-21 09:29:39 -05:00
Eric Eastwood
962d5cecbf Revert "Fixup after LruCache changes revert"
This reverts commit 9f82f66c76.
2025-05-21 09:28:46 -05:00
Eric Eastwood
e36c6f7803 Revert "Reapply "Revert LruCache CacheManager changes for now""
This reverts commit 3b12305376.
2025-05-21 09:28:36 -05:00
Eric Eastwood
827b78554f Reapply "WIP: @cached progress"
This reverts commit b4ed25e4fb.
2025-05-21 09:28:27 -05:00
Eric Eastwood
57546bffad Fix in-flight gauges 2025-05-20 16:15:51 -05:00
Eric Eastwood
9f82f66c76 Fixup after LruCache changes revert 2025-05-20 16:11:44 -05:00
Eric Eastwood
3b12305376 Reapply "Revert LruCache CacheManager changes for now"
This reverts commit a707a25389.
2025-05-20 16:10:36 -05:00
Eric Eastwood
b4ed25e4fb Revert "WIP: @cached progress"
This reverts commit f68211bd0c.
2025-05-20 16:10:23 -05:00
Eric Eastwood
356792fe6d Add to correct registry 2025-05-20 16:09:33 -05:00
Eric Eastwood
f75ea5cfcd Fix DictionaryCache 2025-05-20 16:01:05 -05:00
Eric Eastwood
f68211bd0c WIP: @cached progress 2025-05-20 15:27:50 -05:00
Eric Eastwood
a707a25389 Revert "Revert LruCache CacheManager changes for now"
This reverts commit ccd0a71395.
2025-05-20 15:06:38 -05:00
Eric Eastwood
627a77bc5e Update Measure and @measure_func 2025-05-20 15:04:34 -05:00
Eric Eastwood
6314f6cba0 Revert "Fix lints"
This reverts commit 4a5c2f89c7.
2025-05-20 14:22:22 -05:00
Eric Eastwood
4a5c2f89c7 Fix lints 2025-05-20 14:21:57 -05:00
Eric Eastwood
fc04be1bed Merge branch 'develop' into madlittlemods/hs-specific-metrics
Conflicts:
	synapse/app/generic_worker.py
	synapse/app/homeserver.py
2025-05-20 14:21:19 -05:00
Eric Eastwood
2521a17ef4 Add changelog 2025-05-20 14:16:24 -05:00
Eric Eastwood
e72d782189 Fix current lints 2025-05-20 14:15:33 -05:00
Eric Eastwood
efa6018519 Move LaterGauge further along 2025-05-20 13:58:02 -05:00
Eric Eastwood
65080f8464 More cleanup 2025-05-20 13:35:00 -05:00
Eric Eastwood
1400e155b2 Fix most lints 2025-05-20 13:29:12 -05:00
Eric Eastwood
ccd0a71395 Revert LruCache CacheManager changes for now 2025-05-20 13:24:49 -05:00
Eric Eastwood
4018aa4d98 Fix incorrect @cache_in_self underscore prefix in tests 2025-05-20 13:17:07 -05:00
Eric Eastwood
f49789bfd0 Fix LruCache @overload 2025-05-20 13:03:49 -05:00
Eric Eastwood
9943cd39ad Fix return lints 2025-05-20 12:53:51 -05:00
Eric Eastwood
d3d228ea2d More cache updates (LruCache not finished) 2025-05-19 16:59:17 -05:00
Eric Eastwood
d3c23f8235 Partial changes for CacheManager 2025-05-19 16:09:16 -05:00
Eric Eastwood
3de2c0970e Move jemalloc metrics further along 2025-05-19 14:26:27 -05:00
Eric Eastwood
3215897de6 Try organize some of the global metrics 2025-05-16 17:54:39 -05:00
Eric Eastwood
86f39b04a6 Partial Counter update 2025-05-16 17:10:22 -05:00
Eric Eastwood
72b3becb89 Refactor more custom Collector to be stubbed to use hs.metrics_collector_registry 2025-05-15 16:49:39 -05:00
Eric Eastwood
a6dd8a96bb Refactor our custom Collector to accept a registry 2025-05-15 16:47:36 -05:00
Eric Eastwood
9c6863e1a7 Remove metrics listener type in favor of http listener with metrics resource 2025-05-15 16:20:41 -05:00
Eric Eastwood
c07d3108cc Move a couple metrics to homeserver specific CollectorRegistry 2025-05-15 15:45:26 -05:00
258 changed files with 2953 additions and 4370 deletions

View File

@@ -5,7 +5,7 @@ name: Build docker images
on:
push:
tags: ["v*"]
branches: [master, main, develop]
branches: [ master, main, develop ]
workflow_dispatch:
permissions:
@@ -14,21 +14,23 @@ permissions:
id-token: write # needed for signing the images with GitHub OIDC Token
jobs:
build:
name: Build and push image for ${{ matrix.platform }}
runs-on: ${{ matrix.runs_on }}
strategy:
matrix:
include:
- platform: linux/amd64
runs_on: ubuntu-24.04
suffix: linux-amd64
- platform: linux/arm64
runs_on: ubuntu-24.04-arm
suffix: linux-arm64
runs-on: ubuntu-22.04
steps:
- name: Set up QEMU
id: qemu
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
with:
platforms: arm64
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
- name: Inspect builder
run: docker buildx inspect
- name: Install Cosign
uses: sigstore/cosign-installer@3454372f43399081ed03b604cb2d021dabca52bb # v3.8.2
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
@@ -53,79 +55,13 @@ jobs:
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push by digest
id: build
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
with:
push: true
labels: |
gitsha1=${{ github.sha }}
org.opencontainers.image.version=${{ env.SYNAPSE_VERSION }}
tags: |
docker.io/matrixdotorg/synapse
ghcr.io/element-hq/synapse
file: "docker/Dockerfile"
platforms: ${{ matrix.platform }}
outputs: type=image,push-by-digest=true,name-canonical=true,push=true
- name: Export digest
run: |
mkdir -p ${{ runner.temp }}/digests
digest="${{ steps.build.outputs.digest }}"
touch "${{ runner.temp }}/digests/${digest#sha256:}"
- name: Upload digest
uses: actions/upload-artifact@v4
with:
name: digests-${{ matrix.suffix }}
path: ${{ runner.temp }}/digests/*
if-no-files-found: error
retention-days: 1
merge:
name: Push merged images to ${{ matrix.repository }}
runs-on: ubuntu-latest
strategy:
matrix:
repository:
- docker.io/matrixdotorg/synapse
- ghcr.io/element-hq/synapse
needs:
- build
steps:
- name: Download digests
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
path: ${{ runner.temp }}/digests
pattern: digests-*
merge-multiple: true
- name: Log in to DockerHub
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
if: ${{ startsWith(matrix.repository, 'docker.io') }}
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Log in to GHCR
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
if: ${{ startsWith(matrix.repository, 'ghcr.io') }}
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
- name: Install Cosign
uses: sigstore/cosign-installer@398d4b0eeef1380460a10c8013a76f728fb906ac # v3.9.1
- name: Calculate docker image tag
id: set-tag
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0
with:
images: ${{ matrix.repository }}
images: |
docker.io/matrixdotorg/synapse
ghcr.io/element-hq/synapse
flavor: |
latest=false
tags: |
@@ -133,23 +69,31 @@ jobs:
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/master' }}
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }}
type=pep440,pattern={{raw}}
type=sha
- name: Create manifest list and push
working-directory: ${{ runner.temp }}/digests
env:
REPOSITORY: ${{ matrix.repository }}
run: |
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf "$REPOSITORY@sha256:%s " *)
- name: Build and push all platforms
id: build-and-push
uses: docker/build-push-action@1dc73863535b631f98b2378be8619f83b136f4a0 # v6.17.0
with:
push: true
labels: |
gitsha1=${{ github.sha }}
org.opencontainers.image.version=${{ env.SYNAPSE_VERSION }}
tags: "${{ steps.set-tag.outputs.tags }}"
file: "docker/Dockerfile"
platforms: linux/amd64,linux/arm64
- name: Sign each manifest
# arm64 builds OOM without the git fetch setting. c.f.
# https://github.com/rust-lang/cargo/issues/10583
build-args: |
CARGO_NET_GIT_FETCH_WITH_CLI=true
- name: Sign the images with GitHub OIDC Token
env:
REPOSITORY: ${{ matrix.repository }}
DIGEST: ${{ steps.build-and-push.outputs.digest }}
TAGS: ${{ steps.set-tag.outputs.tags }}
run: |
DIGESTS=""
for TAG in $(echo "$DOCKER_METADATA_OUTPUT_JSON" | jq -r '.tags[]'); do
DIGEST="$(docker buildx imagetools inspect $TAG --format '{{json .Manifest}}' | jq -r '.digest')"
DIGESTS="$DIGESTS $REPOSITORY@$DIGEST"
images=""
for tag in ${TAGS}; do
images+="${tag}@${DIGEST} "
done
cosign sign --yes $DIGESTS
cosign sign --yes ${images}

View File

@@ -6,11 +6,6 @@ name: Attempt to automatically fix linting errors
on:
workflow_dispatch:
env:
# We use nightly so that `fmt` correctly groups together imports, and
# clippy correctly fixes up the benchmarks.
RUST_VERSION: nightly-2025-06-24
jobs:
fixup:
name: Fix up
@@ -21,11 +16,13 @@ jobs:
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Install Rust
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
uses: dtolnay/rust-toolchain@56f84321dbccf38fb67ce29ab63e4754056677e0 # master (rust 1.85.1)
with:
toolchain: ${{ env.RUST_VERSION }}
# We use nightly so that `fmt` correctly groups together imports, and
# clippy correctly fixes up the benchmarks.
toolchain: nightly-2022-12-01
components: clippy, rustfmt
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
- name: Setup Poetry
uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0
@@ -47,6 +44,6 @@ jobs:
- run: cargo fmt
continue-on-error: true
- uses: stefanzweifel/git-auto-commit-action@778341af668090896ca464160c2def5d1d1a3eb0 # v6.0.1
- uses: stefanzweifel/git-auto-commit-action@b863ae1933cb653a53c021fe36dbb774e1fb9403 # v5.2.0
with:
commit_message: "Attempt to fix linting"

View File

@@ -21,9 +21,6 @@ concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
RUST_VERSION: 1.87.0
jobs:
check_repo:
# Prevent this workflow from running on any fork of Synapse other than element-hq/synapse, as it is
@@ -44,10 +41,8 @@ jobs:
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Install Rust
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
with:
toolchain: ${{ env.RUST_VERSION }}
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
uses: dtolnay/rust-toolchain@fcf085fcb4b4b8f63f96906cd713eb52181b5ea4 # stable (rust 1.85.1)
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
# The dev dependencies aren't exposed in the wheel metadata (at least with current
# poetry-core versions), so we install with poetry.
@@ -60,7 +55,7 @@ jobs:
- run: poetry run pip list > before.txt
# Upgrade all runtime dependencies only. This is intended to mimic a fresh
# `pip install matrix-synapse[all]` as closely as possible.
- run: poetry update --without dev
- run: poetry update --no-dev
- run: poetry run pip list > after.txt && (diff -u before.txt after.txt || true)
- name: Remove unhelpful options from mypy config
run: sed -e '/warn_unused_ignores = True/d' -e '/warn_redundant_casts = True/d' -i mypy.ini
@@ -80,10 +75,8 @@ jobs:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Install Rust
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
with:
toolchain: ${{ env.RUST_VERSION }}
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
uses: dtolnay/rust-toolchain@fcf085fcb4b4b8f63f96906cd713eb52181b5ea4 # stable (rust 1.85.1)
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
- run: sudo apt-get -qq install xmlsec1
- name: Set up PostgreSQL ${{ matrix.postgres-version }}
@@ -155,10 +148,8 @@ jobs:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Install Rust
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
with:
toolchain: ${{ env.RUST_VERSION }}
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
uses: dtolnay/rust-toolchain@fcf085fcb4b4b8f63f96906cd713eb52181b5ea4 # stable (rust 1.85.1)
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
- name: Ensure sytest runs `pip install`
# Delete the lockfile so sytest will `pip install` rather than `poetry install`

View File

@@ -30,7 +30,7 @@ jobs:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: "3.x"
python-version: '3.x'
- id: set-distros
run: |
# if we're running from a tag, get the full list of distros; otherwise just use debian:sid
@@ -61,7 +61,7 @@ jobs:
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
with:
install: true
@@ -76,7 +76,7 @@ jobs:
- name: Set up python
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: "3.x"
python-version: '3.x'
- name: Build the packages
# see https://github.com/docker/build-push-action/issues/252
@@ -107,15 +107,12 @@ jobs:
path: debs/*
build-wheels:
name: Build wheels on ${{ matrix.os }}
name: Build wheels on ${{ matrix.os }} for ${{ matrix.arch }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os:
- ubuntu-24.04
- ubuntu-24.04-arm
- macos-13 # This uses x86-64
- macos-14 # This uses arm64
os: [ubuntu-22.04, macos-13]
arch: [x86_64, aarch64]
# is_pr is a flag used to exclude certain jobs from the matrix on PRs.
# It is not read by the rest of the workflow.
is_pr:
@@ -125,11 +122,12 @@ jobs:
# Don't build macos wheels on PR CI.
- is_pr: true
os: "macos-13"
- is_pr: true
os: "macos-14"
# Don't build aarch64 wheels on mac.
- os: "macos-13"
arch: aarch64
# Don't build aarch64 wheels on PR CI.
- is_pr: true
os: "ubuntu-24.04-arm"
arch: aarch64
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
@@ -141,11 +139,21 @@ jobs:
python-version: "3.x"
- name: Install cibuildwheel
run: python -m pip install cibuildwheel==3.0.0
run: python -m pip install cibuildwheel==2.23.0
- name: Set up QEMU to emulate aarch64
if: matrix.arch == 'aarch64'
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
with:
platforms: arm64
- name: Build aarch64 wheels
if: matrix.arch == 'aarch64'
run: echo 'CIBW_ARCHS_LINUX=aarch64' >> $GITHUB_ENV
- name: Only build a single wheel on PR
if: startsWith(github.ref, 'refs/pull/')
run: echo "CIBW_BUILD="cp39-manylinux_*"" >> $GITHUB_ENV
run: echo "CIBW_BUILD="cp39-manylinux_${{ matrix.arch }}"" >> $GITHUB_ENV
- name: Build wheels
run: python -m cibuildwheel --output-dir wheelhouse
@@ -153,10 +161,13 @@ jobs:
# Skip testing for platforms which various libraries don't have wheels
# for, and so need extra build deps.
CIBW_TEST_SKIP: pp3*-* *i686* *musl*
# Fix Rust OOM errors on emulated aarch64: https://github.com/rust-lang/cargo/issues/10583
CARGO_NET_GIT_FETCH_WITH_CLI: true
CIBW_ENVIRONMENT_PASS_LINUX: CARGO_NET_GIT_FETCH_WITH_CLI
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: Wheel-${{ matrix.os }}
name: Wheel-${{ matrix.os }}-${{ matrix.arch }}
path: ./wheelhouse/*.whl
build-sdist:
@@ -168,7 +179,7 @@ jobs:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: "3.10"
python-version: '3.10'
- run: pip install build
@@ -180,6 +191,7 @@ jobs:
name: Sdist
path: dist/*.tar.gz
# if it's a tag, create a release and attach the artifacts to it
attach-assets:
name: "Attach assets to release"

View File

@@ -11,9 +11,6 @@ concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
RUST_VERSION: 1.87.0
jobs:
# Job to detect what has changed so we don't run e.g. Rust checks on PRs that
# don't modify Rust code.
@@ -88,10 +85,8 @@ jobs:
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Install Rust
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
with:
toolchain: ${{ env.RUST_VERSION }}
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
uses: dtolnay/rust-toolchain@c1678930c21fb233e4987c4ae12158f9125e5762 # 1.81.0
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
- uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0
with:
python-version: "3.x"
@@ -154,10 +149,8 @@ jobs:
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Install Rust
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
with:
toolchain: ${{ env.RUST_VERSION }}
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
uses: dtolnay/rust-toolchain@c1678930c21fb233e4987c4ae12158f9125e5762 # 1.81.0
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
- name: Setup Poetry
uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0
@@ -217,10 +210,8 @@ jobs:
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Install Rust
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
with:
toolchain: ${{ env.RUST_VERSION }}
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
uses: dtolnay/rust-toolchain@c1678930c21fb233e4987c4ae12158f9125e5762 # 1.81.0
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
- uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0
with:
poetry-version: "2.1.1"
@@ -236,11 +227,10 @@ jobs:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Install Rust
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
uses: dtolnay/rust-toolchain@0d72692bcfbf448b1e2afa01a67f71b455a9dcec # 1.86.0
with:
components: clippy
toolchain: ${{ env.RUST_VERSION }}
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
- run: cargo clippy -- -D warnings
@@ -255,11 +245,11 @@ jobs:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Install Rust
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
uses: dtolnay/rust-toolchain@56f84321dbccf38fb67ce29ab63e4754056677e0 # master (rust 1.85.1)
with:
toolchain: nightly-2025-04-23
components: clippy
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
- run: cargo clippy --all-features -- -D warnings
@@ -272,12 +262,12 @@ jobs:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Install Rust
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
uses: dtolnay/rust-toolchain@56f84321dbccf38fb67ce29ab63e4754056677e0 # master (rust 1.85.1)
with:
# We use nightly so that it correctly groups together imports
toolchain: nightly-2025-04-23
components: rustfmt
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
- run: cargo fmt --check
@@ -372,10 +362,8 @@ jobs:
postgres:${{ matrix.job.postgres-version }}
- name: Install Rust
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
with:
toolchain: ${{ env.RUST_VERSION }}
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
uses: dtolnay/rust-toolchain@c1678930c21fb233e4987c4ae12158f9125e5762 # 1.81.0
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
- uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0
with:
@@ -416,10 +404,8 @@ jobs:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Install Rust
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
with:
toolchain: ${{ env.RUST_VERSION }}
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
uses: dtolnay/rust-toolchain@c1678930c21fb233e4987c4ae12158f9125e5762 # 1.81.0
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
# There aren't wheels for some of the older deps, so we need to install
# their build dependencies
@@ -533,10 +519,8 @@ jobs:
run: cat sytest-blacklist .ci/worker-blacklist > synapse-blacklist-with-workers
- name: Install Rust
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
with:
toolchain: ${{ env.RUST_VERSION }}
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
uses: dtolnay/rust-toolchain@c1678930c21fb233e4987c4ae12158f9125e5762 # 1.81.0
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
- name: Run SyTest
run: /bootstrap.sh synapse
@@ -679,10 +663,8 @@ jobs:
path: synapse
- name: Install Rust
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
with:
toolchain: ${{ env.RUST_VERSION }}
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
uses: dtolnay/rust-toolchain@c1678930c21fb233e4987c4ae12158f9125e5762 # 1.81.0
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
- name: Prepare Complement's Prerequisites
run: synapse/.ci/scripts/setup_complement_prerequisites.sh
@@ -713,10 +695,8 @@ jobs:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Install Rust
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
with:
toolchain: ${{ env.RUST_VERSION }}
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
uses: dtolnay/rust-toolchain@c1678930c21fb233e4987c4ae12158f9125e5762 # 1.81.0
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
- run: cargo test
@@ -733,10 +713,10 @@ jobs:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Install Rust
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
uses: dtolnay/rust-toolchain@56f84321dbccf38fb67ce29ab63e4754056677e0 # master (rust 1.85.1)
with:
toolchain: nightly-2022-12-01
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
- run: cargo bench --no-run

View File

@@ -20,9 +20,6 @@ concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
RUST_VERSION: 1.87.0
jobs:
check_repo:
# Prevent this workflow from running on any fork of Synapse other than element-hq/synapse, as it is
@@ -46,10 +43,8 @@ jobs:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Install Rust
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
with:
toolchain: ${{ env.RUST_VERSION }}
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
uses: dtolnay/rust-toolchain@fcf085fcb4b4b8f63f96906cd713eb52181b5ea4 # stable (rust 1.85.1)
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
- uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0
with:
@@ -74,10 +69,8 @@ jobs:
- run: sudo apt-get -qq install xmlsec1
- name: Install Rust
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
with:
toolchain: ${{ env.RUST_VERSION }}
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
uses: dtolnay/rust-toolchain@fcf085fcb4b4b8f63f96906cd713eb52181b5ea4 # stable (rust 1.85.1)
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
- uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0
with:
@@ -120,10 +113,8 @@ jobs:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Install Rust
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
with:
toolchain: ${{ env.RUST_VERSION }}
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
uses: dtolnay/rust-toolchain@fcf085fcb4b4b8f63f96906cd713eb52181b5ea4 # stable (rust 1.85.1)
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
- name: Patch dependencies
# Note: The poetry commands want to create a virtualenv in /src/.venv/,

1
.gitignore vendored
View File

@@ -47,7 +47,6 @@ __pycache__/
/.idea/
/.ropeproject/
/.vscode/
/.zed/
# build products
!/.coveragerc

View File

@@ -1,148 +1,3 @@
# Synapse 1.134.0 (2025-07-15)
No significant changes since 1.134.0rc1.
# Synapse 1.134.0rc1 (2025-07-09)
### Features
- Support for [MSC4235](https://github.com/matrix-org/matrix-spec-proposals/pull/4235): `via` query param for hierarchy endpoint. Contributed by Krishan (@kfiven). ([\#18070](https://github.com/element-hq/synapse/issues/18070))
- Add `forget_forced_upon_leave` capability as per [MSC4267](https://github.com/matrix-org/matrix-spec-proposals/pull/4267). ([\#18196](https://github.com/element-hq/synapse/issues/18196))
- Add `federated_user_may_invite` spam checker callback which receives the entire invite event. Contributed by @tulir @ Beeper. ([\#18241](https://github.com/element-hq/synapse/issues/18241))
### Bugfixes
- Fix `KeyError` on background updates when using split main/state databases. ([\#18509](https://github.com/element-hq/synapse/issues/18509))
- Improve performance of device deletion by adding missing index. ([\#18582](https://github.com/element-hq/synapse/issues/18582))
- Fix `avatar_url` and `displayname` being sent on federation profile queries when they are not set. ([\#18593](https://github.com/element-hq/synapse/issues/18593))
- Respond with 401 & `M_USER_LOCKED` when a locked user calls `POST /login`, as per the spec. ([\#18594](https://github.com/element-hq/synapse/issues/18594))
- Ensure policy servers are not asked to scan policy server change events, allowing rooms to disable the use of a policy server while the policy server is down. ([\#18605](https://github.com/element-hq/synapse/issues/18605))
### Improved Documentation
- Fix documentation of the Delete Room Admin API's status field. ([\#18519](https://github.com/element-hq/synapse/issues/18519))
### Deprecations and Removals
- Stop adding the "origin" field to newly-created events (PDUs). ([\#18418](https://github.com/element-hq/synapse/issues/18418))
### Internal Changes
- Replace `PyICU` crate with equivalent `icu_segmenter` Rust crate. ([\#18553](https://github.com/element-hq/synapse/issues/18553), [\#18646](https://github.com/element-hq/synapse/issues/18646))
- Improve docstring on `simple_upsert_many`. ([\#18573](https://github.com/element-hq/synapse/issues/18573))
- Raise poetry-core version cap to 2.1.3. ([\#18575](https://github.com/element-hq/synapse/issues/18575))
- Raise setuptools_rust version cap to 1.11.1. ([\#18576](https://github.com/element-hq/synapse/issues/18576))
- Better handling of ratelimited requests. ([\#18595](https://github.com/element-hq/synapse/issues/18595), [\#18600](https://github.com/element-hq/synapse/issues/18600))
- Update to Rust 1.87.0 in CI, and bump the pinned commit of the `dtolnay/rust-toolchain` GitHub Action to `b3b07ba8b418998c39fb20f53e8b695cdcc8de1b`. ([\#18596](https://github.com/element-hq/synapse/issues/18596))
- Speed up bulk device deletion. ([\#18602](https://github.com/element-hq/synapse/issues/18602))
- Speed up the building of arm-based wheels in CI. ([\#18618](https://github.com/element-hq/synapse/issues/18618))
- Speed up the building of Docker images in CI. ([\#18620](https://github.com/element-hq/synapse/issues/18620))
- Add `.zed/` directory to `.gitignore`. ([\#18623](https://github.com/element-hq/synapse/issues/18623))
- Log the room ID we're purging state for. ([\#18625](https://github.com/element-hq/synapse/issues/18625))
### Updates to locked dependencies
* Bump Swatinem/rust-cache from 2.7.8 to 2.8.0. ([\#18612](https://github.com/element-hq/synapse/issues/18612))
* Bump attrs from 24.2.0 to 25.3.0. ([\#18649](https://github.com/element-hq/synapse/issues/18649))
* Bump authlib from 1.5.2 to 1.6.0. ([\#18642](https://github.com/element-hq/synapse/issues/18642))
* Bump base64 from 0.21.7 to 0.22.1. ([\#18589](https://github.com/element-hq/synapse/issues/18589))
* Bump base64 from 0.21.7 to 0.22.1. ([\#18629](https://github.com/element-hq/synapse/issues/18629))
* Bump docker/build-push-action from 6.17.0 to 6.18.0. ([\#18497](https://github.com/element-hq/synapse/issues/18497))
* Bump docker/setup-buildx-action from 3.10.0 to 3.11.1. ([\#18587](https://github.com/element-hq/synapse/issues/18587))
* Bump hiredis from 3.1.0 to 3.2.1. ([\#18638](https://github.com/element-hq/synapse/issues/18638))
* Bump ijson from 3.3.0 to 3.4.0. ([\#18650](https://github.com/element-hq/synapse/issues/18650))
* Bump jsonschema from 4.23.0 to 4.24.0. ([\#18630](https://github.com/element-hq/synapse/issues/18630))
* Bump msgpack from 1.1.0 to 1.1.1. ([\#18651](https://github.com/element-hq/synapse/issues/18651))
* Bump mypy-zope from 1.0.11 to 1.0.12. ([\#18640](https://github.com/element-hq/synapse/issues/18640))
* Bump phonenumbers from 9.0.2 to 9.0.8. ([\#18652](https://github.com/element-hq/synapse/issues/18652))
* Bump pillow from 11.2.1 to 11.3.0. ([\#18624](https://github.com/element-hq/synapse/issues/18624))
* Bump prometheus-client from 0.21.0 to 0.22.1. ([\#18609](https://github.com/element-hq/synapse/issues/18609))
* Bump pyasn1-modules from 0.4.1 to 0.4.2. ([\#18495](https://github.com/element-hq/synapse/issues/18495))
* Bump pydantic from 2.11.4 to 2.11.7. ([\#18639](https://github.com/element-hq/synapse/issues/18639))
* Bump reqwest from 0.12.15 to 0.12.20. ([\#18590](https://github.com/element-hq/synapse/issues/18590))
* Bump reqwest from 0.12.20 to 0.12.22. ([\#18627](https://github.com/element-hq/synapse/issues/18627))
* Bump ruff from 0.11.11 to 0.12.1. ([\#18645](https://github.com/element-hq/synapse/issues/18645))
* Bump ruff from 0.12.1 to 0.12.2. ([\#18657](https://github.com/element-hq/synapse/issues/18657))
* Bump sentry-sdk from 2.22.0 to 2.32.0. ([\#18633](https://github.com/element-hq/synapse/issues/18633))
* Bump setuptools-rust from 1.10.2 to 1.11.1. ([\#18655](https://github.com/element-hq/synapse/issues/18655))
* Bump sigstore/cosign-installer from 3.8.2 to 3.9.0. ([\#18588](https://github.com/element-hq/synapse/issues/18588))
* Bump sigstore/cosign-installer from 3.9.0 to 3.9.1. ([\#18608](https://github.com/element-hq/synapse/issues/18608))
* Bump stefanzweifel/git-auto-commit-action from 5.2.0 to 6.0.1. ([\#18607](https://github.com/element-hq/synapse/issues/18607))
* Bump tokio from 1.45.1 to 1.46.0. ([\#18628](https://github.com/element-hq/synapse/issues/18628))
* Bump tokio from 1.46.0 to 1.46.1. ([\#18667](https://github.com/element-hq/synapse/issues/18667))
* Bump treq from 24.9.1 to 25.5.0. ([\#18610](https://github.com/element-hq/synapse/issues/18610))
* Bump types-bleach from 6.2.0.20241123 to 6.2.0.20250514. ([\#18634](https://github.com/element-hq/synapse/issues/18634))
* Bump types-jsonschema from 4.23.0.20250516 to 4.24.0.20250528. ([\#18611](https://github.com/element-hq/synapse/issues/18611))
* Bump types-opentracing from 2.4.10.6 to 2.4.10.20250622. ([\#18586](https://github.com/element-hq/synapse/issues/18586))
* Bump types-psycopg2 from 2.9.21.20250318 to 2.9.21.20250516. ([\#18658](https://github.com/element-hq/synapse/issues/18658))
* Bump types-pyyaml from 6.0.12.20241230 to 6.0.12.20250516. ([\#18643](https://github.com/element-hq/synapse/issues/18643))
* Bump types-setuptools from 75.2.0.20241019 to 80.9.0.20250529. ([\#18644](https://github.com/element-hq/synapse/issues/18644))
* Bump typing-extensions from 4.12.2 to 4.14.0. ([\#18654](https://github.com/element-hq/synapse/issues/18654))
* Bump typing-extensions from 4.14.0 to 4.14.1. ([\#18668](https://github.com/element-hq/synapse/issues/18668))
* Bump urllib3 from 2.2.2 to 2.5.0. ([\#18572](https://github.com/element-hq/synapse/issues/18572))
# Synapse 1.133.0 (2025-07-01)
Pre-built wheels are now built using the [manylinux_2_28](https://github.com/pypa/manylinux#manylinux_2_28-almalinux-8-based) base, which is expected to be compatible with distros using glibc 2.28 or later, including:
- Debian 10+
- Ubuntu 18.10+
- Fedora 29+
- CentOS/RHEL 8+
Previously, wheels were built using the [manylinux2014](https://github.com/pypa/manylinux#manylinux2014-centos-7-based-glibc-217) base, which was expected to be compatible with distros using glibc 2.17 or later.
### Bugfixes
- Bump `cibuildwheel` to 3.0.0 to fix the `manylinux` wheel builds. ([\#18615](https://github.com/element-hq/synapse/issues/18615))
# Synapse 1.133.0rc1 (2025-06-24)
### Features
- Add support for the [MSC4260 user report API](https://github.com/matrix-org/matrix-spec-proposals/pull/4260). ([\#18120](https://github.com/element-hq/synapse/issues/18120))
### Bugfixes
- Fix an issue where, during state resolution for v11 rooms, Synapse would incorrectly calculate the power level of the creator when there was no power levels event in the room. ([\#18534](https://github.com/element-hq/synapse/issues/18534), [\#18547](https://github.com/element-hq/synapse/issues/18547))
- Fix long-standing bug where sliding sync did not honour the `room_id_to_include` config option. ([\#18535](https://github.com/element-hq/synapse/issues/18535))
- Fix an issue where "Lock timeout is getting excessive" warnings would be logged even when the lock timeout was <10 minutes. ([\#18543](https://github.com/element-hq/synapse/issues/18543))
- Fix an issue where Synapse could calculate the wrong power level for the creator of the room if there was no power levels event. ([\#18545](https://github.com/element-hq/synapse/issues/18545))
### Improved Documentation
- Generate config documentation from JSON Schema file. ([\#18528](https://github.com/element-hq/synapse/issues/18528))
- Fix typo in user type documentation. ([\#18568](https://github.com/element-hq/synapse/issues/18568))
### Internal Changes
- Increase performance of introspecting access tokens when using delegated auth. ([\#18357](https://github.com/element-hq/synapse/issues/18357), [\#18561](https://github.com/element-hq/synapse/issues/18561))
- Log user deactivations. ([\#18541](https://github.com/element-hq/synapse/issues/18541))
- Enable [`flake8-logging`](https://docs.astral.sh/ruff/rules/#flake8-logging-log) and [`flake8-logging-format`](https://docs.astral.sh/ruff/rules/#flake8-logging-format-g) rules in Ruff and fix related issues throughout the codebase. ([\#18542](https://github.com/element-hq/synapse/issues/18542))
- Clean up old, unused rows from the `device_federation_inbox` table. ([\#18546](https://github.com/element-hq/synapse/issues/18546))
- Run config schema CI on develop and release branches. ([\#18551](https://github.com/element-hq/synapse/issues/18551))
- Add support for Twisted `25.5.0`+ releases. ([\#18577](https://github.com/element-hq/synapse/issues/18577))
- Update PyO3 to version 0.25. ([\#18578](https://github.com/element-hq/synapse/issues/18578))
### Updates to locked dependencies
* Bump actions/setup-python from 5.5.0 to 5.6.0. ([\#18555](https://github.com/element-hq/synapse/issues/18555))
* Bump base64 from 0.21.7 to 0.22.1. ([\#18559](https://github.com/element-hq/synapse/issues/18559))
* Bump dawidd6/action-download-artifact from 9 to 11. ([\#18556](https://github.com/element-hq/synapse/issues/18556))
* Bump headers from 0.4.0 to 0.4.1. ([\#18529](https://github.com/element-hq/synapse/issues/18529))
* Bump requests from 2.32.2 to 2.32.4. ([\#18533](https://github.com/element-hq/synapse/issues/18533))
* Bump types-requests from 2.32.0.20250328 to 2.32.4.20250611. ([\#18558](https://github.com/element-hq/synapse/issues/18558))
# Synapse 1.132.0 (2025-06-17)
### Improved Documentation

472
Cargo.lock generated
View File

@@ -62,9 +62,15 @@ dependencies = [
"miniz_oxide",
"object",
"rustc-demangle",
"windows-targets",
"windows-targets 0.52.6",
]
[[package]]
name = "base64"
version = "0.21.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
[[package]]
name = "base64"
version = "0.22.1"
@@ -144,15 +150,6 @@ version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]]
name = "core_maths"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77745e017f5edba1a9c1d854f6f3a52dac8a12dd5af5d2f54aecf61e43d80d30"
dependencies = [
"libm",
]
[[package]]
name = "cpufeatures"
version = "0.2.12"
@@ -334,7 +331,7 @@ dependencies = [
"cfg-if",
"libc",
"wasi 0.13.3+wasi-0.2.2",
"windows-targets",
"windows-targets 0.52.6",
]
[[package]]
@@ -374,7 +371,7 @@ version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3314d5adb5d94bcdf56771f2e50dbbc80bb4bdf88967526706205ac9eff24eb"
dependencies = [
"base64",
"base64 0.22.1",
"bytes",
"headers-core",
"http",
@@ -490,21 +487,17 @@ dependencies = [
[[package]]
name = "hyper-util"
version = "0.1.14"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc2fdfdbff08affe55bb779f33b053aa1fe5dd5b54c257343c17edfa55711bdb"
checksum = "497bbc33a26fdd4af9ed9c70d63f61cf56a938375fbb32df34db9b1cd6d643f2"
dependencies = [
"base64",
"bytes",
"futures-channel",
"futures-core",
"futures-util",
"http",
"http-body",
"hyper",
"ipnet",
"libc",
"percent-encoding",
"pin-project-lite",
"socket2",
"tokio",
@@ -519,59 +512,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526"
dependencies = [
"displaydoc",
"yoke 0.7.5",
"yoke",
"zerofrom",
"zerovec 0.10.4",
"zerovec",
]
[[package]]
name = "icu_collections"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47"
dependencies = [
"displaydoc",
"potential_utf",
"yoke 0.8.0",
"zerofrom",
"zerovec 0.11.2",
]
[[package]]
name = "icu_locale"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ae5921528335e91da1b6c695dbf1ec37df5ac13faa3f91e5640be93aa2fbefd"
dependencies = [
"displaydoc",
"icu_collections 2.0.0",
"icu_locale_core",
"icu_locale_data",
"icu_provider 2.0.0",
"potential_utf",
"tinystr 0.8.1",
"zerovec 0.11.2",
]
[[package]]
name = "icu_locale_core"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a"
dependencies = [
"displaydoc",
"litemap 0.8.0",
"tinystr 0.8.1",
"writeable 0.6.1",
"zerovec 0.11.2",
]
[[package]]
name = "icu_locale_data"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fdef0c124749d06a743c69e938350816554eb63ac979166590e2b4ee4252765"
[[package]]
name = "icu_locid"
version = "1.5.0"
@@ -579,10 +524,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637"
dependencies = [
"displaydoc",
"litemap 0.7.5",
"tinystr 0.7.6",
"writeable 0.5.5",
"zerovec 0.10.4",
"litemap",
"tinystr",
"writeable",
"zerovec",
]
[[package]]
@@ -594,9 +539,9 @@ dependencies = [
"displaydoc",
"icu_locid",
"icu_locid_transform_data",
"icu_provider 1.5.0",
"tinystr 0.7.6",
"zerovec 0.10.4",
"icu_provider",
"tinystr",
"zerovec",
]
[[package]]
@@ -612,15 +557,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f"
dependencies = [
"displaydoc",
"icu_collections 1.5.0",
"icu_collections",
"icu_normalizer_data",
"icu_properties",
"icu_provider 1.5.0",
"icu_provider",
"smallvec",
"utf16_iter",
"utf8_iter",
"write16",
"zerovec 0.10.4",
"zerovec",
]
[[package]]
@@ -636,12 +581,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5"
dependencies = [
"displaydoc",
"icu_collections 1.5.0",
"icu_collections",
"icu_locid_transform",
"icu_properties_data",
"icu_provider 1.5.0",
"tinystr 0.7.6",
"zerovec 0.10.4",
"icu_provider",
"tinystr",
"zerovec",
]
[[package]]
@@ -660,28 +605,11 @@ dependencies = [
"icu_locid",
"icu_provider_macros",
"stable_deref_trait",
"tinystr 0.7.6",
"writeable 0.5.5",
"yoke 0.7.5",
"tinystr",
"writeable",
"yoke",
"zerofrom",
"zerovec 0.10.4",
]
[[package]]
name = "icu_provider"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af"
dependencies = [
"displaydoc",
"icu_locale_core",
"stable_deref_trait",
"tinystr 0.8.1",
"writeable 0.6.1",
"yoke 0.8.0",
"zerofrom",
"zerotrie",
"zerovec 0.11.2",
"zerovec",
]
[[package]]
@@ -695,30 +623,6 @@ dependencies = [
"syn",
]
[[package]]
name = "icu_segmenter"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e185fc13b6401c138cf40db12b863b35f5edf31b88192a545857b41aeaf7d3d3"
dependencies = [
"core_maths",
"displaydoc",
"icu_collections 2.0.0",
"icu_locale",
"icu_locale_core",
"icu_provider 2.0.0",
"icu_segmenter_data",
"potential_utf",
"utf8_iter",
"zerovec 0.11.2",
]
[[package]]
name = "icu_segmenter_data"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5360a2fbe97f617c4f8b944356dedb36d423f7da7f13c070995cf89e59f01220"
[[package]]
name = "idna"
version = "1.0.3"
@@ -756,33 +660,12 @@ version = "2.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5"
[[package]]
name = "io-uring"
version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b86e202f00093dcba4275d4636b93ef9dd75d025ae560d2521b45ea28ab49013"
dependencies = [
"bitflags",
"cfg-if",
"libc",
]
[[package]]
name = "ipnet"
version = "2.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
[[package]]
name = "iri-string"
version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2"
dependencies = [
"memchr",
"serde",
]
[[package]]
name = "itoa"
version = "1.0.11"
@@ -811,24 +694,12 @@ version = "0.2.172"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
[[package]]
name = "libm"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de"
[[package]]
name = "litemap"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856"
[[package]]
name = "litemap"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956"
[[package]]
name = "log"
version = "0.4.27"
@@ -921,16 +792,6 @@ version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0"
[[package]]
name = "potential_utf"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585"
dependencies = [
"serde",
"zerovec 0.11.2",
]
[[package]]
name = "ppv-lite86"
version = "0.2.17"
@@ -948,11 +809,12 @@ dependencies = [
[[package]]
name = "pyo3"
version = "0.25.1"
version = "0.24.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8970a78afe0628a3e3430376fc5fd76b6b45c4d43360ffd6cdd40bdde72b682a"
checksum = "e5203598f366b11a02b13aa20cab591229ff0a89fd121a308a5df751d5fc9219"
dependencies = [
"anyhow",
"cfg-if",
"indoc",
"libc",
"memoffset",
@@ -966,9 +828,9 @@ dependencies = [
[[package]]
name = "pyo3-build-config"
version = "0.25.1"
version = "0.24.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "458eb0c55e7ece017adeba38f2248ff3ac615e53660d7c71a238d7d2a01c7598"
checksum = "99636d423fa2ca130fa5acde3059308006d46f98caac629418e53f7ebb1e9999"
dependencies = [
"once_cell",
"target-lexicon",
@@ -976,9 +838,9 @@ dependencies = [
[[package]]
name = "pyo3-ffi"
version = "0.25.1"
version = "0.24.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7114fe5457c61b276ab77c5055f206295b812608083644a5c5b2640c3102565c"
checksum = "78f9cf92ba9c409279bc3305b5409d90db2d2c22392d443a87df3a1adad59e33"
dependencies = [
"libc",
"pyo3-build-config",
@@ -997,9 +859,9 @@ dependencies = [
[[package]]
name = "pyo3-macros"
version = "0.25.1"
version = "0.24.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8725c0a622b374d6cb051d11a0983786448f7785336139c3c94f5aa6bef7e50"
checksum = "0b999cb1a6ce21f9a6b147dcf1be9ffedf02e0043aec74dc390f3007047cecd9"
dependencies = [
"proc-macro2",
"pyo3-macros-backend",
@@ -1009,9 +871,9 @@ dependencies = [
[[package]]
name = "pyo3-macros-backend"
version = "0.25.1"
version = "0.24.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4109984c22491085343c05b0dbc54ddc405c3cf7b4374fc533f5c3313a572ccc"
checksum = "822ece1c7e1012745607d5cf0bcb2874769f0f7cb34c4cde03b9358eb9ef911a"
dependencies = [
"heck",
"proc-macro2",
@@ -1022,9 +884,9 @@ dependencies = [
[[package]]
name = "pythonize"
version = "0.25.0"
version = "0.24.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "597907139a488b22573158793aa7539df36ae863eba300c75f3a0d65fc475e27"
checksum = "d5bcac0d0b71821f0d69e42654f1e15e5c94b85196446c4de9588951a2117e7b"
dependencies = [
"pyo3",
"serde",
@@ -1180,11 +1042,11 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "reqwest"
version = "0.12.22"
version = "0.12.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cbc931937e6ca3a06e3b6c0aa7841849b160a90351d6ab467a8b9b9959767531"
checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb"
dependencies = [
"base64",
"base64 0.22.1",
"bytes",
"futures-core",
"futures-util",
@@ -1195,13 +1057,17 @@ dependencies = [
"hyper",
"hyper-rustls",
"hyper-util",
"ipnet",
"js-sys",
"log",
"mime",
"once_cell",
"percent-encoding",
"pin-project-lite",
"quinn",
"rustls",
"rustls-native-certs",
"rustls-pemfile",
"rustls-pki-types",
"serde",
"serde_json",
@@ -1211,13 +1077,13 @@ dependencies = [
"tokio-rustls",
"tokio-util",
"tower",
"tower-http",
"tower-service",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"wasm-streams",
"web-sys",
"windows-registry",
]
[[package]]
@@ -1272,6 +1138,15 @@ dependencies = [
"security-framework",
]
[[package]]
name = "rustls-pemfile"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50"
dependencies = [
"rustls-pki-types",
]
[[package]]
name = "rustls-pki-types"
version = "1.11.0"
@@ -1458,7 +1333,7 @@ name = "synapse"
version = "0.1.0"
dependencies = [
"anyhow",
"base64",
"base64 0.21.7",
"blake2",
"bytes",
"futures",
@@ -1466,7 +1341,6 @@ dependencies = [
"hex",
"http",
"http-body-util",
"icu_segmenter",
"lazy_static",
"log",
"mime",
@@ -1535,17 +1409,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f"
dependencies = [
"displaydoc",
"zerovec 0.10.4",
]
[[package]]
name = "tinystr"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b"
dependencies = [
"displaydoc",
"zerovec 0.11.2",
"zerovec",
]
[[package]]
@@ -1565,17 +1429,15 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
version = "1.46.1"
version = "1.45.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0cc3a2344dafbe23a245241fe8b09735b521110d30fcefbbd5feb1797ca35d17"
checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779"
dependencies = [
"backtrace",
"bytes",
"io-uring",
"libc",
"mio",
"pin-project-lite",
"slab",
"socket2",
"windows-sys 0.52.0",
]
@@ -1618,24 +1480,6 @@ dependencies = [
"tower-service",
]
[[package]]
name = "tower-http"
version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2"
dependencies = [
"bitflags",
"bytes",
"futures-util",
"http",
"http-body",
"iri-string",
"pin-project-lite",
"tower",
"tower-layer",
"tower-service",
]
[[package]]
name = "tower-layer"
version = "0.3.3"
@@ -1864,13 +1708,48 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "windows-link"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
[[package]]
name = "windows-registry"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3"
dependencies = [
"windows-result",
"windows-strings",
"windows-targets 0.53.0",
]
[[package]]
name = "windows-result"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252"
dependencies = [
"windows-link",
]
[[package]]
name = "windows-strings"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319"
dependencies = [
"windows-link",
]
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets",
"windows-targets 0.52.6",
]
[[package]]
@@ -1879,7 +1758,7 @@ version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
"windows-targets",
"windows-targets 0.52.6",
]
[[package]]
@@ -1888,14 +1767,30 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
"windows_aarch64_gnullvm 0.52.6",
"windows_aarch64_msvc 0.52.6",
"windows_i686_gnu 0.52.6",
"windows_i686_gnullvm 0.52.6",
"windows_i686_msvc 0.52.6",
"windows_x86_64_gnu 0.52.6",
"windows_x86_64_gnullvm 0.52.6",
"windows_x86_64_msvc 0.52.6",
]
[[package]]
name = "windows-targets"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b"
dependencies = [
"windows_aarch64_gnullvm 0.53.0",
"windows_aarch64_msvc 0.53.0",
"windows_i686_gnu 0.53.0",
"windows_i686_gnullvm 0.53.0",
"windows_i686_msvc 0.53.0",
"windows_x86_64_gnu 0.53.0",
"windows_x86_64_gnullvm 0.53.0",
"windows_x86_64_msvc 0.53.0",
]
[[package]]
@@ -1904,48 +1799,96 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_aarch64_msvc"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnu"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_gnullvm"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_i686_msvc"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnu"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "windows_x86_64_msvc"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
[[package]]
name = "wit-bindgen-rt"
version = "0.33.0"
@@ -1967,12 +1910,6 @@ version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
[[package]]
name = "writeable"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb"
[[package]]
name = "yoke"
version = "0.7.5"
@@ -1981,19 +1918,7 @@ checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40"
dependencies = [
"serde",
"stable_deref_trait",
"yoke-derive 0.7.5",
"zerofrom",
]
[[package]]
name = "yoke"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc"
dependencies = [
"serde",
"stable_deref_trait",
"yoke-derive 0.8.0",
"yoke-derive",
"zerofrom",
]
@@ -2009,18 +1934,6 @@ dependencies = [
"synstructure",
]
[[package]]
name = "yoke-derive"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6"
dependencies = [
"proc-macro2",
"quote",
"syn",
"synstructure",
]
[[package]]
name = "zerocopy"
version = "0.8.17"
@@ -2068,35 +1981,15 @@ version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"
[[package]]
name = "zerotrie"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595"
dependencies = [
"displaydoc",
]
[[package]]
name = "zerovec"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079"
dependencies = [
"yoke 0.7.5",
"yoke",
"zerofrom",
"zerovec-derive 0.10.3",
]
[[package]]
name = "zerovec"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428"
dependencies = [
"yoke 0.8.0",
"zerofrom",
"zerovec-derive 0.11.1",
"zerovec-derive",
]
[[package]]
@@ -2109,14 +2002,3 @@ dependencies = [
"quote",
"syn",
]
[[package]]
name = "zerovec-derive"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f"
dependencies = [
"proc-macro2",
"quote",
"syn",
]

View File

@@ -1 +0,0 @@
Add `recaptcha_private_key_path` and `recaptcha_public_key_path` config option.

View File

@@ -0,0 +1 @@
Add support for the [MSC4260 user report API](https://github.com/matrix-org/matrix-spec-proposals/pull/4260).

View File

@@ -1 +0,0 @@
Add plain-text handling for rich-text topics as per [MSC3765](https://github.com/matrix-org/matrix-spec-proposals/pull/3765).

View File

@@ -1 +0,0 @@
If enabled by the user, server admins will see [soft failed](https://spec.matrix.org/v1.13/server-server-api/#soft-failure) events over the Client-Server API.

View File

@@ -1 +0,0 @@
Add experimental support for [MSC4277](https://github.com/matrix-org/matrix-spec-proposals/pull/4277).

1
changelog.d/18357.misc Normal file
View File

@@ -0,0 +1 @@
Increase performance of introspecting access tokens when using delegated auth.

1
changelog.d/18443.misc Normal file
View File

@@ -0,0 +1 @@
Refactor metrics to collect in homeserver-specific registry.

View File

@@ -1 +0,0 @@
Fix CPU and database spinning when retrying sending events to servers whilst at the same time purging those events.

View File

@@ -1 +0,0 @@
Add ability to limit amount uploaded by a user in a given time period.

1
changelog.d/18528.doc Normal file
View File

@@ -0,0 +1 @@
Generate config documentation from JSON Schema file.

1
changelog.d/18534.bugfix Normal file
View File

@@ -0,0 +1 @@
Fix an issue where during state resolution for v11 rooms Synapse would incorrectly calculate the power level of the creator when there was no power levels event in the room.

1
changelog.d/18535.bugfix Normal file
View File

@@ -0,0 +1 @@
Fix long-standing bug where sliding sync did not honour the `room_id_to_include` config option.

1
changelog.d/18541.misc Normal file
View File

@@ -0,0 +1 @@
Log user deactivations.

1
changelog.d/18542.misc Normal file
View File

@@ -0,0 +1 @@
Enable [`flake8-logging`](https://docs.astral.sh/ruff/rules/#flake8-logging-log) and [`flake8-logging-format`](https://docs.astral.sh/ruff/rules/#flake8-logging-format-g) rules in Ruff and fix related issues throughout the codebase.

1
changelog.d/18543.bugfix Normal file
View File

@@ -0,0 +1 @@
Fix an issue where "Lock timeout is getting excessive" warnings would be logged even when the lock timeout was <10 minutes.

1
changelog.d/18545.bugfix Normal file
View File

@@ -0,0 +1 @@
Fix an issue where Synapse could calculate the wrong power level for the creator of the room if there was no power levels event.

1
changelog.d/18546.misc Normal file
View File

@@ -0,0 +1 @@
Clean up old, unused rows from the `device_federation_inbox` table.

1
changelog.d/18547.bugfix Normal file
View File

@@ -0,0 +1 @@
Fix an issue where during state resolution for v11 rooms Synapse would incorrectly calculate the power level of the creator when there was no power levels event in the room.

View File

@@ -1 +0,0 @@
Document that some config options for the user directory are in violation of the Matrix spec.

1
changelog.d/18551.misc Normal file
View File

@@ -0,0 +1 @@
Run config schema CI on develop and release branches.

View File

@@ -1 +0,0 @@
Allow user registrations to be done on workers.

1
changelog.d/18561.misc Normal file
View File

@@ -0,0 +1 @@
Increase performance of introspecting access tokens when using delegated auth.

View File

@@ -1 +0,0 @@
Remove unnecessary HTTP replication calls.

1
changelog.d/18568.doc Normal file
View File

@@ -0,0 +1 @@
Fix typo in user type documentation.

View File

@@ -1 +0,0 @@
Refactor `Measure` block metrics to be homeserver-scoped.

View File

@@ -1 +0,0 @@
Unbreak "Latest dependencies" workflow by using the `--without dev` poetry option instead of removed `--no-dev`.

View File

@@ -1 +0,0 @@
Raise minimum Python version to `3.9.12`.

View File

@@ -1 +0,0 @@
Update URL Preview code to work with `lxml` 6.0.0+.

View File

@@ -1 +0,0 @@
Use `markdown-it-py` instead of `commonmark` in the release script.

View File

@@ -1 +0,0 @@
Advertise support for Matrix v1.12.

View File

@@ -1 +0,0 @@
Fix typing errors with upgraded mypy version.

View File

@@ -1 +0,0 @@
Add doc comment explaining that config files are shallowly merged.

View File

@@ -1 +0,0 @@
Minor speed up of insertion into `stream_positions` table.

View File

@@ -1 +0,0 @@
Remove unused `allow_no_prev_events` option when creating an event.

View File

@@ -1 +0,0 @@
Add `recaptcha_private_key_path` and `recaptcha_public_key_path` config option.

View File

@@ -45,10 +45,6 @@ def make_graph(pdus: List[dict], filename_prefix: str) -> None:
colors = {"red", "green", "blue", "yellow", "purple"}
for pdu in pdus:
# TODO: The "origin" field has since been removed from events generated
# by Synapse. We should consider removing it here as well but since this
# is part of `contrib/`, it is left for the community to revise and ensure things
# still work correctly.
origins.add(pdu.get("origin"))
color_map = {color: color for color in colors if color in origins}

24
debian/changelog vendored
View File

@@ -1,27 +1,3 @@
matrix-synapse-py3 (1.134.0) stable; urgency=medium
* New Synapse release 1.134.0.
-- Synapse Packaging team <packages@matrix.org> Tue, 15 Jul 2025 14:22:50 +0100
matrix-synapse-py3 (1.134.0~rc1) stable; urgency=medium
* New Synapse release 1.134.0rc1.
-- Synapse Packaging team <packages@matrix.org> Wed, 09 Jul 2025 11:27:13 +0100
matrix-synapse-py3 (1.133.0) stable; urgency=medium
* New synapse release 1.133.0.
-- Synapse Packaging team <packages@matrix.org> Tue, 01 Jul 2025 13:13:24 +0000
matrix-synapse-py3 (1.133.0~rc1) stable; urgency=medium
* New Synapse release 1.133.0rc1.
-- Synapse Packaging team <packages@matrix.org> Tue, 24 Jun 2025 11:57:47 +0100
matrix-synapse-py3 (1.132.0) stable; urgency=medium
* New Synapse release 1.132.0.

View File

@@ -74,7 +74,6 @@
- [Users](admin_api/user_admin_api.md)
- [Server Version](admin_api/version_api.md)
- [Federation](usage/administration/admin_api/federation.md)
- [Client-Server API Extensions](admin_api/client_server_api_extensions.md)
- [Manhole](manhole.md)
- [Monitoring](metrics-howto.md)
- [Reporting Homeserver Usage Statistics](usage/administration/monitoring/reporting_homeserver_usage_statistics.md)

View File

@@ -1,25 +0,0 @@
# Client-Server API Extensions
Server administrators can set special account data to change how the Client-Server API behaves for
their clients. Setting the account data, or having it already set, as a non-admin has no effect.
All configuration options can be set through the `io.element.synapse.admin_client_config` global
account data on the admin's user account.
Example:
```
PUT /_matrix/client/v3/user/{adminUserId}/account_data/io.element.synapse.admin_client_config
{
"return_soft_failed_events": true
}
```
## See soft failed events
Learn more about soft failure from [the spec](https://spec.matrix.org/v1.14/server-server-api/#soft-failure).
To receive soft failed events in APIs like `/sync` and `/messages`, set `return_soft_failed_events`
to `true` in the admin client config. When `false`, the normal behaviour of these endpoints is to
exclude soft failed events.
Default: `false`

View File

@@ -117,6 +117,7 @@ It returns a JSON body like the following:
"hashes": {
"sha256": "xK1//xnmvHJIOvbgXlkI8eEqdvoMmihVDJ9J4SNlsAw"
},
"origin": "matrix.org",
"origin_server_ts": 1592291711430,
"prev_events": [
"$YK4arsKKcc0LRoe700pS8DSjOvUT4NDv0HfInlMFw2M"

View File

@@ -806,7 +806,7 @@ A response body like the following is returned:
}, {
"delete_id": "delete_id2",
"room_id": "!roomid:example.com",
"status": "active",
"status": "purging",
"shutdown_room": {
"kicked_users": [
"@foobar:example.com"
@@ -843,7 +843,7 @@ A response body like the following is returned:
```json
{
"status": "active",
"status": "purging",
"delete_id": "bHkCNQpHqOaFhPtK",
"room_id": "!roomid:example.com",
"shutdown_room": {
@@ -876,8 +876,8 @@ The following fields are returned in the JSON response body:
- `delete_id` - The ID for this purge
- `room_id` - The ID of the room being deleted
- `status` - The status will be one of:
- `scheduled` - The deletion is waiting to be started
- `active` - The process is purging the room and event data from database.
- `shutting_down` - The process is removing users from the room.
- `purging` - The process is purging the room and event data from database.
- `complete` - The process has completed successfully.
- `failed` - The process is aborted, an error has occurred.
- `error` - A string that shows an error message if `status` is `failed`.

View File

@@ -29,6 +29,8 @@ easiest way of installing the latest version is to use [rustup](https://rustup.r
Synapse can connect to PostgreSQL via the [psycopg2](https://pypi.org/project/psycopg2/) Python library. Building this library from source requires access to PostgreSQL's C header files. On Debian or Ubuntu Linux, these can be installed with `sudo apt install libpq-dev`.
Synapse has an optional, improved user search with better Unicode support. For that you need the development package of `libicu`. On Debian or Ubuntu Linux, this can be installed with `sudo apt install libicu-dev`.
The source code of Synapse is hosted on GitHub. You will also need [a recent version of git](https://github.com/git-guides/install-git).
For some tests, you will need [a recent version of Docker](https://docs.docker.com/get-docker/).

View File

@@ -164,7 +164,10 @@ $ poetry cache clear --all .
# including the wheel artifacts which is not covered by the above command
# (see https://github.com/python-poetry/poetry/issues/10304)
#
# This is necessary in order to rebuild or fetch new wheels.
# This is necessary in order to rebuild or fetch new wheels. For example, if you update
# the `icu` library in on your system, you will need to rebuild the PyICU Python package
# in order to incorporate the correct dynamically linked library locations otherwise you
# will run into errors like: `ImportError: libicui18n.so.75: cannot open shared object file: No such file or directory`
$ rm -rf $(poetry config cache-dir)
```

View File

@@ -53,15 +53,17 @@
type: http
x_forwarded: true
bind_addresses: ['::1', '127.0.0.1']
resources:
- names: [client, federation]
compress: false
# beginning of the new metrics listener
- port: 9000
type: metrics
type: http
bind_addresses: ['::1', '127.0.0.1']
resources:
- names: [metrics]
compress: false
```
1. Restart Synapse.

View File

@@ -80,8 +80,6 @@ Called when processing an invitation, both when one is created locally or when
receiving an invite over federation. Both inviter and invitee are represented by
their Matrix user ID (e.g. `@alice:example.com`).
Note that federated invites will call `federated_user_may_invite` before this callback.
The callback must return one of:
- `synapse.module_api.NOT_SPAM`, to allow the operation. Other callbacks may still
@@ -99,34 +97,6 @@ be used. If this happens, Synapse will not call any of the subsequent implementa
this callback.
### `federated_user_may_invite`
_First introduced in Synapse v1.133.0_
```python
async def federated_user_may_invite(event: "synapse.events.EventBase") -> Union["synapse.module_api.NOT_SPAM", "synapse.module_api.errors.Codes", bool]
```
Called when processing an invitation received over federation. Unlike `user_may_invite`,
this callback receives the entire event, including any stripped state in the `unsigned`
section, not just the room and user IDs.
The callback must return one of:
- `synapse.module_api.NOT_SPAM`, to allow the operation. Other callbacks may still
decide to reject it.
- `synapse.module_api.errors.Codes` to reject the operation with an error code. In case
of doubt, `synapse.module_api.errors.Codes.FORBIDDEN` is a good error code.
If multiple modules implement this callback, they will be considered in order. If a
callback returns `synapse.module_api.NOT_SPAM`, Synapse falls through to the next one.
The value of the first callback that does not return `synapse.module_api.NOT_SPAM` will
be used. If this happens, Synapse will not call any of the subsequent implementations of
this callback.
If all of the callbacks return `synapse.module_api.NOT_SPAM`, Synapse will also fall
through to the `user_may_invite` callback before approving the invite.
### `user_may_send_3pid_invite`
_First introduced in Synapse v1.45.0_

View File

@@ -286,7 +286,7 @@ Installing prerequisites on Ubuntu or Debian:
```sh
sudo apt install build-essential python3-dev libffi-dev \
python3-pip python3-setuptools sqlite3 \
libssl-dev virtualenv libjpeg-dev libxslt1-dev
libssl-dev virtualenv libjpeg-dev libxslt1-dev libicu-dev
```
##### ArchLinux
@@ -295,7 +295,7 @@ Installing prerequisites on ArchLinux:
```sh
sudo pacman -S base-devel python python-pip \
python-setuptools python-virtualenv sqlite3
python-setuptools python-virtualenv sqlite3 icu
```
##### CentOS/Fedora
@@ -305,7 +305,8 @@ Installing prerequisites on CentOS or Fedora Linux:
```sh
sudo dnf install libtiff-devel libjpeg-devel libzip-devel freetype-devel \
libwebp-devel libxml2-devel libxslt-devel libpq-devel \
python3-virtualenv libffi-devel openssl-devel python3-devel
python3-virtualenv libffi-devel openssl-devel python3-devel \
libicu-devel
sudo dnf group install "Development Tools"
```
@@ -332,7 +333,7 @@ dnf install python3.12 python3.12-devel
```
Finally, install common prerequisites
```bash
dnf install libpq5 libpq5-devel lz4 pkgconf
dnf install libicu libicu-devel libpq5 libpq5-devel lz4 pkgconf
dnf group install "Development Tools"
```
###### Using venv module instead of virtualenv command
@@ -364,6 +365,20 @@ xcode-select --install
Some extra dependencies may be needed. You can use Homebrew (https://brew.sh) for them.
You may need to install icu, and make the icu binaries and libraries accessible.
Please follow [the official instructions of PyICU](https://pypi.org/project/PyICU/) to do so.
If you're struggling to get icu discovered, and see:
```
RuntimeError:
Please install pkg-config on your system or set the ICU_VERSION environment
variable to the version of ICU you have installed.
```
despite it being installed and having your `PATH` updated, you can omit this dependency by
not specifying `--extras all` to `poetry`. If using postgres, you can install Synapse via
`poetry install --extras saml2 --extras oidc --extras postgres --extras opentracing --extras redis --extras sentry`.
ICU is not a hard dependency on getting a working installation.
On ARM-based Macs you may also need to install libjpeg and libpq:
```sh
brew install jpeg libpq
@@ -385,7 +400,8 @@ Installing prerequisites on openSUSE:
```sh
sudo zypper in -t pattern devel_basis
sudo zypper in python-pip python-setuptools sqlite3 python-virtualenv \
python-devel libffi-devel libopenssl-devel libjpeg62-devel
python-devel libffi-devel libopenssl-devel libjpeg62-devel \
libicu-devel
```
##### OpenBSD

View File

@@ -117,21 +117,6 @@ each upgrade are complete before moving on to the next upgrade, to avoid
stacking them up. You can monitor the currently running background updates with
[the Admin API](usage/administration/admin_api/background_updates.html#status).
# Upgrading to v1.135.0
## `on_user_registration` module API callback may now run on any worker
Previously, the `on_user_registration` callback would only run on the main
process. Modules relying on this callback must assume that they may now be
called from any worker, not just the main process.
# Upgrading to v1.134.0
## ICU bundled with Synapse
Synapse now uses the Rust `icu` library for improved user search. Installing the
native ICU library on your system is no longer required.
# Upgrading to v1.130.0
## Documented endpoint which can be delegated to a federation worker

View File

@@ -2086,23 +2086,6 @@ Example configuration:
max_upload_size: 60M
```
---
### `media_upload_limits`
*(array)* A list of media upload limits defining how much data a given user can upload in a given time period.
An empty list means no limits are applied.
Defaults to `[]`.
Example configuration:
```yaml
media_upload_limits:
- time_period: 1h
max_size: 100M
- time_period: 1w
max_size: 500M
```
---
### `max_image_pixels`
*(byte size)* Maximum number of pixels that will be thumbnailed. Defaults to `"32M"`.
@@ -2357,21 +2340,6 @@ Example configuration:
recaptcha_public_key: YOUR_PUBLIC_KEY
```
---
### `recaptcha_public_key_path`
*(string|null)* An alternative to [`recaptcha_public_key`](#recaptcha_public_key): allows the public key to be specified in an external file.
The file should be a plain text file, containing only the public key. Synapse reads the public key from the given file once at startup.
_Added in Synapse 1.135.0._
Defaults to `null`.
Example configuration:
```yaml
recaptcha_public_key_path: /path/to/key/file
```
---
### `recaptcha_private_key`
*(string|null)* This homeserver's ReCAPTCHA private key. Must be specified if [`enable_registration_captcha`](#enable_registration_captcha) is enabled. Defaults to `null`.
@@ -2381,21 +2349,6 @@ Example configuration:
recaptcha_private_key: YOUR_PRIVATE_KEY
```
---
### `recaptcha_private_key_path`
*(string|null)* An alternative to [`recaptcha_private_key`](#recaptcha_private_key): allows the private key to be specified in an external file.
The file should be a plain text file, containing only the private key. Synapse reads the private key from the given file once at startup.
_Added in Synapse 1.135.0._
Defaults to `null`.
Example configuration:
```yaml
recaptcha_private_key_path: /path/to/key/file
```
---
### `enable_registration_captcha`
*(boolean)* Set to `true` to require users to complete a CAPTCHA test when registering an account. Requires a valid ReCaptcha public/private key.
@@ -3808,11 +3761,7 @@ encryption_enabled_by_default_for_room_type: invite
This setting has the following sub-options:
* `enabled` (boolean): Defines whether users can search the user directory. If `false` then empty responses are returned to all queries.
*Warning: While the homeserver may determine which subset of users are searched, the Matrix specification requires homeservers to include (at minimum) users visible in public rooms and users sharing a room with the requester. Using `false` improves performance but violates this requirement.*
Defaults to `true`.
* `enabled` (boolean): Defines whether users can search the user directory. If false then empty responses are returned to all queries. Defaults to `true`.
* `search_all_users` (boolean): Defines whether to search all users visible to your homeserver at the time the search is performed. If set to true, will return all users known to the homeserver matching the search query. If false, search results will only contain users visible in public rooms and users sharing a room with the requester.

View File

@@ -77,11 +77,14 @@ The user provided search term is lowercased and normalized using [NFKC](https://
this treats the string as case-insensitive, canonicalizes different forms of the
same text, and maps some "roughly equivalent" characters together.
The search term is then split into segments using the [`icu_segmenter`
Rust crate](https://crates.io/crates/icu_segmenter). This crate ships with its
own dictionary and Long Short Term-Memory (LSTM) machine learning models
per-language to segment words. Read more [in the crate's
documentation](https://docs.rs/icu/latest/icu/segmenter/struct.WordSegmenter.html#method.new_auto).
The search term is then split into words:
* If [ICU](https://en.wikipedia.org/wiki/International_Components_for_Unicode) is
available, then the system's [default locale](https://unicode-org.github.io/icu/userguide/locale/#default-locales)
will be used to break the search term into words. (See the
[installation instructions](setup/installation.md) for how to install ICU.)
* If unavailable, then runs of ASCII characters, numbers, underscores, and hyphens
are considered words.
The queries for PostgreSQL and SQLite are detailed below, but their overall goal
is to find matching users, preferring users who are "real" (e.g. not bots,

View File

@@ -96,6 +96,7 @@
gnumake
# Native dependencies for running Synapse.
icu
libffi
libjpeg
libpqxx

1159
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -101,7 +101,7 @@ module-name = "synapse.synapse_rust"
[tool.poetry]
name = "matrix-synapse"
version = "1.134.0"
version = "1.132.0"
description = "Homeserver for the Matrix decentralised comms protocol"
authors = ["Matrix.org Team and Contributors <packages@matrix.org>"]
license = "AGPL-3.0-or-later"
@@ -159,13 +159,7 @@ synapse_review_recent_signups = "synapse._scripts.review_recent_signups:main"
update_synapse_database = "synapse._scripts.update_synapse_database:main"
[tool.poetry.dependencies]
# We aim to support all versions of Python currently supported upstream as per
# our dependency deprecation policy:
# https://element-hq.github.io/synapse/latest/deprecation_policy.html#policy
#
# 3.9.12 is currently the minimum version due to Twisted requiring it:
# https://github.com/twisted/twisted/commit/27674f64d8a553ad5e68913bfb1c936e6fdeb46a
python = "^3.9.12"
python = "^3.9.0"
# Mandatory Dependencies
# ----------------------
@@ -230,7 +224,7 @@ pydantic = ">=1.7.4, <3"
# https://github.com/python-poetry/poetry/issues/6154). Both `pip install` and
# `poetry build` do the right thing without this explicit dependency.
#
# This isn't really a dev-dependency, as `poetry install --without dev` will fail,
# This isn't really a dev-dependency, as `poetry install --no-dev` will fail,
# but the alternative is to add it to the main list of deps where it isn't
# needed.
setuptools_rust = ">=1.3"
@@ -260,6 +254,7 @@ hiredis = { version = "*", optional = true }
Pympler = { version = "*", optional = true }
parameterized = { version = ">=0.7.4", optional = true }
idna = { version = ">=2.5", optional = true }
pyicu = { version = ">=2.10.2", optional = true }
[tool.poetry.extras]
# NB: Packages that should be part of `pip install matrix-synapse[all]` need to be specified
@@ -282,6 +277,10 @@ redis = ["txredisapi", "hiredis"]
# Required to use experimental `caches.track_memory_usage` config option.
cache-memory = ["pympler"]
test = ["parameterized", "idna"]
# Allows for better search for international characters in the user directory. This
# requires libicu's development headers installed on the system (e.g. libicu-dev on
# Debian-based distributions).
user-search = ["pyicu"]
# The duplication here is awful. I hate hate hate hate hate it. However, for now I want
# to ensure you can still `pip install matrix-synapse[all]` like today. Two motivations:
@@ -313,6 +312,8 @@ all = [
"txredisapi", "hiredis",
# cache-memory
"pympler",
# improved user search
"pyicu",
# omitted:
# - test: it's useful to have this separate from dev deps in the olddeps job
# - systemd: this is a system-based requirement
@@ -323,7 +324,7 @@ all = [
# failing on new releases. Keeping lower bounds loose here means that dependabot
# can bump versions without having to update the content-hash in the lockfile.
# This helps prevents merge conflicts when running a batch of dependabot updates.
ruff = "0.12.2"
ruff = "0.11.11"
# Type checking only works with the pydantic.v1 compat module from pydantic v2
pydantic = "^2"
@@ -332,6 +333,7 @@ lxml-stubs = ">=0.4.0"
mypy = "*"
mypy-zope = "*"
types-bleach = ">=4.1.0"
types-commonmark = ">=0.9.2"
types-jsonschema = ">=3.2.0"
types-netaddr = ">=0.8.0.6"
types-opentracing = ">=2.4.2"
@@ -354,7 +356,7 @@ idna = ">=2.5"
click = ">=8.1.3"
# GitPython was == 3.1.14; bumped to 3.1.20, the first release with type hints.
GitPython = ">=3.1.20"
markdown-it-py = ">=3.0.0"
commonmark = ">=0.9.1"
pygithub = ">=1.55"
# The following are executed as commands by the release script.
twine = "*"
@@ -372,7 +374,7 @@ tomli = ">=1.2.3"
# runtime errors caused by build system changes.
# We are happy to raise these upper bounds upon request,
# provided we check that it's safe to do so (i.e. that CI passes).
requires = ["poetry-core>=1.1.0,<=2.1.3", "setuptools_rust>=1.3,<=1.11.1"]
requires = ["poetry-core>=1.1.0,<=1.9.1", "setuptools_rust>=1.3,<=1.10.2"]
build-backend = "poetry.core.masonry.api"
@@ -380,10 +382,13 @@ build-backend = "poetry.core.masonry.api"
# Skip unsupported platforms (by us or by Rust).
# See https://cibuildwheel.readthedocs.io/en/stable/options/#build-skip for the list of build targets.
# We skip:
# - CPython and PyPy 3.8: EOLed
# - CPython 3.6, 3.7 and 3.8: EOLed
# - PyPy 3.7 and 3.8: we only support Python 3.9+
# - musllinux i686: excluded to reduce number of wheels we build.
# c.f. https://github.com/matrix-org/synapse/pull/12595#discussion_r963107677
skip = "cp38* pp38* *-musllinux_i686"
# - PyPy on Aarch64 and musllinux on aarch64: too slow to build.
# c.f. https://github.com/matrix-org/synapse/pull/14259
skip = "cp36* cp37* cp38* pp37* pp38* *-musllinux_i686 pp*aarch64 *-musllinux_aarch64"
# Enable non-default builds.
# "pypy" used to be included by default up until cibuildwheel 3.
enable = "pypy"

View File

@@ -30,20 +30,19 @@ http = "1.1.0"
lazy_static = "1.4.0"
log = "0.4.17"
mime = "0.3.17"
pyo3 = { version = "0.25.1", features = [
pyo3 = { version = "0.24.2", features = [
"macros",
"anyhow",
"abi3",
"abi3-py39",
] }
pyo3-log = "0.12.4"
pythonize = "0.25.0"
pyo3-log = "0.12.3"
pythonize = "0.24.0"
regex = "1.6.0"
sha2 = "0.10.8"
serde = { version = "1.0.144", features = ["derive"] }
serde_json = "1.0.85"
ulid = "1.1.2"
icu_segmenter = "2.0.0"
reqwest = { version = "0.12.15", default-features = false, features = [
"http2",
"stream",

View File

@@ -27,7 +27,7 @@ pub enum IdentifierError {
impl fmt::Display for IdentifierError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{self:?}")
write!(f, "{:?}", self)
}
}

View File

@@ -13,7 +13,6 @@ pub mod identifier;
pub mod matrix_const;
pub mod push;
pub mod rendezvous;
pub mod segmenter;
lazy_static! {
static ref LOGGING_HANDLE: ResetHandle = pyo3_log::init();
@@ -54,7 +53,6 @@ fn synapse_rust(py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> {
events::register_module(py, m)?;
http_client::register_module(py, m)?;
rendezvous::register_module(py, m)?;
segmenter::register_module(py, m)?;
Ok(())
}

View File

@@ -1,33 +0,0 @@
use icu_segmenter::options::WordBreakInvariantOptions;
use icu_segmenter::WordSegmenter;
use pyo3::prelude::*;
#[pyfunction]
pub fn parse_words(text: &str) -> PyResult<Vec<String>> {
let segmenter = WordSegmenter::new_auto(WordBreakInvariantOptions::default());
let mut parts = Vec::new();
let mut last = 0usize;
// `segment_str` gives us word boundaries as a vector of indexes. Use that
// to build a vector of words, and return.
for boundary in segmenter.segment_str(text) {
if boundary > last {
parts.push(text[last..boundary].to_string());
}
last = boundary;
}
Ok(parts)
}
pub fn register_module(py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> {
let child_module = PyModule::new(py, "segmenter")?;
child_module.add_function(wrap_pyfunction!(parse_words, m)?)?;
m.add_submodule(&child_module)?;
py.import("sys")?
.getattr("modules")?
.set_item("synapse.synapse_rust.segmenter", child_module)?;
Ok(())
}

View File

@@ -1,5 +1,5 @@
$schema: https://element-hq.github.io/synapse/latest/schema/v1/meta.schema.json
$id: https://element-hq.github.io/synapse/schema/synapse/v1.134/synapse-config.schema.json
$id: https://element-hq.github.io/synapse/schema/synapse/v1.132/synapse-config.schema.json
type: object
properties:
modules:
@@ -451,8 +451,7 @@ properties:
type: string
description: >-
The type of listener. Normally `http`, but other valid options are
[`manhole`](../../manhole.md) and
[`metrics`](../../metrics-howto.md).
[`manhole`](../../manhole.md).
enum:
- http
- manhole
@@ -2335,30 +2334,6 @@ properties:
default: 50M
examples:
- 60M
media_upload_limits:
type: array
description: >-
A list of media upload limits defining how much data a given user can
upload in a given time period.
An empty list means no limits are applied.
default: []
items:
time_period:
type: "#/$defs/duration"
description: >-
The time period over which the limit applies. Required.
max_size:
type: "#/$defs/bytes"
description: >-
Amount of data that can be uploaded in the time period by the user.
Required.
examples:
- - time_period: 1h
max_size: 100M
- time_period: 1w
max_size: 500M
max_image_pixels:
$ref: "#/$defs/bytes"
description: Maximum number of pixels that will be thumbnailed.
@@ -2692,21 +2667,6 @@ properties:
default: null
examples:
- YOUR_PUBLIC_KEY
recaptcha_public_key_path:
type: ["string", "null"]
description: >-
An alternative to [`recaptcha_public_key`](#recaptcha_public_key): allows
the public key to be specified in an external file.
The file should be a plain text file, containing only the public key.
Synapse reads the public key from the given file once at startup.
_Added in Synapse 1.135.0._
default: null
examples:
- /path/to/key/file
recaptcha_private_key:
type: ["string", "null"]
description: >-
@@ -2715,21 +2675,6 @@ properties:
default: null
examples:
- YOUR_PRIVATE_KEY
recaptcha_private_key_path:
type: ["string", "null"]
description: >-
An alternative to [`recaptcha_private_key`](#recaptcha_private_key):
allows the private key to be specified in an external file.
The file should be a plain text file, containing only the private key.
Synapse reads the private key from the given file once at startup.
_Added in Synapse 1.135.0._
default: null
examples:
- /path/to/key/file
enable_registration_captcha:
type: boolean
description: >-
@@ -4719,15 +4664,8 @@ properties:
enabled:
type: boolean
description: >-
Defines whether users can search the user directory. If `false` then
Defines whether users can search the user directory. If false then
empty responses are returned to all queries.
*Warning: While the homeserver may determine which subset of users are
searched, the Matrix specification requires homeservers to include (at
minimum) users visible in public rooms and users sharing a room with
the requester. Using `false` improves performance but violates this
requirement.*
default: true
search_all_users:
type: boolean

View File

@@ -36,11 +36,11 @@ from typing import Any, List, Match, Optional, Union
import attr
import click
import commonmark
import git
from click.exceptions import ClickException
from git import GitCommandError, Repo
from github import BadCredentialsException, Github
from markdown_it import MarkdownIt
from packaging import version
@@ -851,7 +851,7 @@ def get_changes_for_version(wanted_version: version.Version) -> str:
# First we parse the changelog so that we can split it into sections based
# on the release headings.
tokens = MarkdownIt().parse(changes)
ast = commonmark.Parser().parse(changes)
@attr.s(auto_attribs=True)
class VersionSection:
@@ -862,22 +862,19 @@ def get_changes_for_version(wanted_version: version.Version) -> str:
end_line: Optional[int] = None # Is none if its the last entry
headings: List[VersionSection] = []
for i, token in enumerate(tokens):
# We look for level 1 headings (h1 tags).
if token.type != "heading_open" or token.tag != "h1":
for node, _ in ast.walker():
# We look for all text nodes that are in a level 1 heading.
if node.t != "text":
continue
# The next token should be an inline token containing the heading text
if i + 1 < len(tokens) and tokens[i + 1].type == "inline":
heading_text = tokens[i + 1].content
# The map property contains [line_begin, line_end] (0-based)
start_line = token.map[0] if token.map else 0
if node.parent.t != "heading" or node.parent.level != 1:
continue
# If we have a previous heading then we update its `end_line`.
if headings:
headings[-1].end_line = start_line
# If we have a previous heading then we update its `end_line`.
if headings:
headings[-1].end_line = node.parent.sourcepos[0][0] - 1
headings.append(VersionSection(heading_text, start_line))
headings.append(VersionSection(node.literal, node.parent.sourcepos[0][0] - 1))
changes_by_line = changes.split("\n")

View File

@@ -29,7 +29,6 @@ from synapse.api.errors import (
InvalidClientTokenError,
MissingClientTokenError,
UnrecognizedRequestError,
UserLockedError,
)
from synapse.http.site import SynapseRequest
from synapse.logging.opentracing import active_span, force_tracing, start_active_span
@@ -163,7 +162,12 @@ class InternalAuth(BaseAuth):
if not allow_locked and await self.store.get_user_locked_status(
requester.user.to_string()
):
raise UserLockedError()
raise AuthError(
401,
"User account has been locked",
errcode=Codes.USER_LOCKED,
additional_fields={"soft_logout": True},
)
# Deny the request if the user account has expired.
# This check is only done for regular users, not appservice ones.

View File

@@ -207,6 +207,7 @@ class MSC3861DelegatedAuth(BaseAuth):
# the old access token to continue working for a short time.
self._introspection_cache: ResponseCache[str] = ResponseCache(
self._clock,
hs.get_cache_manager(),
"token_introspection",
timeout_ms=120_000,
# don't log because the keys are access tokens

View File

@@ -262,11 +262,6 @@ class EventContentFields:
TOMBSTONE_SUCCESSOR_ROOM: Final = "replacement_room"
# Used in m.room.topic events.
TOPIC: Final = "topic"
M_TOPIC: Final = "m.topic"
M_TEXT: Final = "m.text"
class EventUnsignedContentFields:
"""Fields found inside the 'unsigned' data on events"""
@@ -275,13 +270,6 @@ class EventUnsignedContentFields:
MEMBERSHIP: Final = "membership"
class MTextFields:
"""Fields found inside m.text content blocks."""
BODY: Final = "body"
MIMETYPE: Final = "mimetype"
class RoomTypes:
"""Understood values of the room_type field of m.room.create events."""
@@ -302,9 +290,6 @@ class AccountDataTypes:
MSC4155_INVITE_PERMISSION_CONFIG: Final = (
"org.matrix.msc4155.invite_permission_config"
)
# Synapse-specific behaviour. See "Client-Server API Extensions" documentation
# in Admin API for more information.
SYNAPSE_ADMIN_CLIENT_CONFIG: Final = "io.element.synapse.admin_client_config"
class HistoryVisibility:

View File

@@ -306,20 +306,6 @@ class UserDeactivatedError(SynapseError):
)
class UserLockedError(SynapseError):
"""The error returned to the client when the user attempted to access an
authenticated endpoint, but the account has been locked.
"""
def __init__(self) -> None:
super().__init__(
code=HTTPStatus.UNAUTHORIZED,
msg="User account has been locked",
errcode=Codes.USER_LOCKED,
additional_fields={"soft_logout": True},
)
class FederationDeniedError(SynapseError):
"""An error raised when the server tries to federate with a server which
is not on its federation whitelist.
@@ -541,11 +527,7 @@ class InvalidCaptchaError(SynapseError):
class LimitExceededError(SynapseError):
"""A client has sent too many requests and is being throttled.
Args:
pause: Optional time in seconds to pause before responding to the client.
"""
"""A client has sent too many requests and is being throttled."""
def __init__(
self,
@@ -553,7 +535,6 @@ class LimitExceededError(SynapseError):
code: int = 429,
retry_after_ms: Optional[int] = None,
errcode: str = Codes.LIMIT_EXCEEDED,
pause: Optional[float] = None,
):
# Use HTTP header Retry-After to enable library-assisted retry handling.
headers = (
@@ -564,7 +545,6 @@ class LimitExceededError(SynapseError):
super().__init__(code, "Too Many Requests", errcode, headers=headers)
self.retry_after_ms = retry_after_ms
self.limiter_name = limiter_name
self.pause = pause
def error_dict(self, config: Optional["HomeServerConfig"]) -> "JsonDict":
return cs_error(self.msg, self.errcode, retry_after_ms=self.retry_after_ms)

View File

@@ -338,10 +338,12 @@ class Ratelimiter:
)
if not allowed:
if pause:
await self.clock.sleep(pause)
raise LimitExceededError(
limiter_name=self._limiter_name,
retry_after_ms=int(1000 * (time_allowed - time_now_s)),
pause=pause,
)

View File

@@ -74,9 +74,13 @@ from synapse.handlers.auth import load_legacy_password_auth_providers
from synapse.http.site import SynapseSite
from synapse.logging.context import PreserveLoggingContext
from synapse.logging.opentracing import init_tracer
from synapse.metrics import install_gc_manager, register_threadpool
from synapse.metrics.background_process_metrics import wrap_as_background_process
from synapse.metrics.jemalloc import setup_jemalloc_stats
from synapse.metrics import CPUMetrics, install_gc_manager, register_threadpool
from synapse.metrics._gc import GCCounts, PyPyGCStats, running_on_pypy
from synapse.metrics._reactor_metrics import setup_reactor_metrics
from synapse.metrics.background_process_metrics import (
BackgroundProcessCollector,
wrap_as_background_process,
)
from synapse.module_api.callbacks.spamchecker_callbacks import load_legacy_spam_checkers
from synapse.module_api.callbacks.third_party_event_rules_callbacks import (
load_legacy_third_party_event_rules,
@@ -178,7 +182,6 @@ def start_reactor(
def run() -> None:
logger.info("Running")
setup_jemalloc_stats()
change_resource_limit(soft_file_limit)
if gc_thresholds:
gc.set_threshold(*gc_thresholds)
@@ -283,20 +286,6 @@ def register_start(
reactor.callWhenRunning(lambda: defer.ensureDeferred(wrapper()))
def listen_metrics(bind_addresses: StrCollection, port: int) -> None:
"""
Start Prometheus metrics server.
"""
from prometheus_client import start_http_server as start_http_server_prometheus
from synapse.metrics import RegistryProxy
for host in bind_addresses:
logger.info("Starting metrics listener on %s:%d", host, port)
_set_prometheus_client_use_created_metrics(False)
start_http_server_prometheus(port, addr=host, registry=RegistryProxy)
def _set_prometheus_client_use_created_metrics(new_value: bool) -> None:
"""
Sets whether prometheus_client should expose `_created`-suffixed metrics for
@@ -607,6 +596,7 @@ async def start(hs: "HomeServer") -> None:
)
setup_sentry(hs)
setup_global_metrics(hs)
setup_sdnotify(hs)
# If background tasks are running on the main process or this is the worker in
@@ -694,6 +684,20 @@ def setup_sentry(hs: "HomeServer") -> None:
global_scope.set_tag("worker_name", name)
def setup_global_metrics(hs: "HomeServer") -> None:
"""Set up global metrics for this homeserver.
This is called after the homeserver has been set up, but before any
listeners are started.
"""
CPUMetrics(registry=hs.metrics_collector_registry)
if running_on_pypy:
PyPyGCStats(registry=hs.metrics_collector_registry)
GCCounts(registry=hs.metrics_collector_registry)
BackgroundProcessCollector(registry=hs.metrics_collector_registry)
setup_reactor_metrics(registry=hs.metrics_collector_registry)
def setup_sdnotify(hs: "HomeServer") -> None:
"""Adds process state hooks to tell systemd what we are up to."""

View File

@@ -49,7 +49,7 @@ from synapse.config.server import ListenerConfig, TCPListenerConfig
from synapse.federation.transport.server import TransportLayerServer
from synapse.http.server import JsonResource, OptionsResource
from synapse.logging.context import LoggingContext
from synapse.metrics import METRICS_PREFIX, MetricsResource, RegistryProxy
from synapse.metrics import METRICS_PREFIX, MetricsResource
from synapse.replication.http import REPLICATION_PREFIX, ReplicationRestResource
from synapse.rest import ClientRestResource, admin
from synapse.rest.health import HealthResource
@@ -118,6 +118,7 @@ class GenericWorkerStore(
# FIXME(https://github.com/matrix-org/synapse/issues/3714): We need to add
# UserDirectoryStore as we write directly rather than going via the correct worker.
UserDirectoryStore,
StatsStore,
UIAuthWorkerStore,
EndToEndRoomKeyStore,
PresenceStore,
@@ -153,7 +154,6 @@ class GenericWorkerStore(
StreamWorkerStore,
EventsWorkerStore,
RegistrationWorkerStore,
StatsStore,
SearchStore,
TransactionWorkerStore,
LockStore,
@@ -186,7 +186,9 @@ class GenericWorkerServer(HomeServer):
for res in listener_config.http_options.resources:
for name in res.names:
if name == "metrics":
resources[METRICS_PREFIX] = MetricsResource(RegistryProxy)
resources[METRICS_PREFIX] = MetricsResource(
self.metrics_collector_registry
)
elif name == "client":
resource: Resource = ClientRestResource(self)
@@ -283,23 +285,6 @@ class GenericWorkerServer(HomeServer):
raise ConfigError(
"Can not using a unix socket for manhole at this time."
)
elif listener.type == "metrics":
if not self.config.metrics.enable_metrics:
logger.warning(
"Metrics listener configured, but enable_metrics is not True!"
)
else:
if isinstance(listener, TCPListenerConfig):
_base.listen_metrics(
listener.bind_addresses,
listener.port,
)
else:
raise ConfigError(
"Can not use a unix socket for metrics at this time."
)
else:
logger.warning("Unsupported listener type: %s", listener.type)

View File

@@ -60,7 +60,7 @@ from synapse.http.server import (
StaticResource,
)
from synapse.logging.context import LoggingContext
from synapse.metrics import METRICS_PREFIX, MetricsResource, RegistryProxy
from synapse.metrics import METRICS_PREFIX, MetricsResource
from synapse.replication.http import REPLICATION_PREFIX, ReplicationRestResource
from synapse.rest import ClientRestResource, admin
from synapse.rest.health import HealthResource
@@ -252,7 +252,9 @@ class SynapseHomeServer(HomeServer):
resources[SERVER_KEY_PREFIX] = KeyResource(self)
if name == "metrics" and self.config.metrics.enable_metrics:
metrics_resource: Resource = MetricsResource(RegistryProxy)
metrics_resource: Resource = MetricsResource(
self.metrics_collector_registry
)
if compress:
metrics_resource = gz_wrap(metrics_resource)
resources[METRICS_PREFIX] = metrics_resource
@@ -286,22 +288,6 @@ class SynapseHomeServer(HomeServer):
raise ConfigError(
"Can not use a unix socket for manhole at this time."
)
elif listener.type == "metrics":
if not self.config.metrics.enable_metrics:
logger.warning(
"Metrics listener configured, but enable_metrics is not True!"
)
else:
if isinstance(listener, TCPListenerConfig):
_base.listen_metrics(
listener.bind_addresses,
listener.port,
)
else:
raise ConfigError(
"Can not use a unix socket for metrics at this time."
)
else:
# this shouldn't happen, as the listener type should have been checked
# during parsing

View File

@@ -56,33 +56,6 @@ if TYPE_CHECKING:
logger = logging.getLogger(__name__)
sent_transactions_counter = Counter(
"synapse_appservice_api_sent_transactions",
"Number of /transactions/ requests sent",
["service"],
)
failed_transactions_counter = Counter(
"synapse_appservice_api_failed_transactions",
"Number of /transactions/ requests that failed to send",
["service"],
)
sent_events_counter = Counter(
"synapse_appservice_api_sent_events", "Number of events sent to the AS", ["service"]
)
sent_ephemeral_counter = Counter(
"synapse_appservice_api_sent_ephemeral",
"Number of ephemeral events sent to the AS",
["service"],
)
sent_todevice_counter = Counter(
"synapse_appservice_api_sent_todevice",
"Number of todevice messages sent to the AS",
["service"],
)
HOUR_IN_MS = 60 * 60 * 1000
@@ -130,7 +103,45 @@ class ApplicationServiceApi(SimpleHttpClient):
self.config = hs.config.appservice
self.protocol_meta_cache: ResponseCache[Tuple[str, str]] = ResponseCache(
hs.get_clock(), "as_protocol_meta", timeout_ms=HOUR_IN_MS
hs.get_clock(),
hs.get_cache_manager(),
"as_protocol_meta",
timeout_ms=HOUR_IN_MS,
)
self.sent_transactions_counter = Counter(
"synapse_appservice_api_sent_transactions",
"Number of /transactions/ requests sent",
["service"],
registry=hs.metrics_collector_registry,
)
self.failed_transactions_counter = Counter(
"synapse_appservice_api_failed_transactions",
"Number of /transactions/ requests that failed to send",
["service"],
registry=hs.metrics_collector_registry,
)
self.sent_events_counter = Counter(
"synapse_appservice_api_sent_events",
"Number of events sent to the AS",
["service"],
registry=hs.metrics_collector_registry,
)
self.sent_ephemeral_counter = Counter(
"synapse_appservice_api_sent_ephemeral",
"Number of ephemeral events sent to the AS",
["service"],
registry=hs.metrics_collector_registry,
)
self.sent_todevice_counter = Counter(
"synapse_appservice_api_sent_todevice",
"Number of todevice messages sent to the AS",
["service"],
registry=hs.metrics_collector_registry,
)
def _get_headers(self, service: "ApplicationService") -> Dict[bytes, List[bytes]]:
@@ -395,10 +406,10 @@ class ApplicationServiceApi(SimpleHttpClient):
service.url,
[event.get("event_id") for event in events],
)
sent_transactions_counter.labels(service.id).inc()
sent_events_counter.labels(service.id).inc(len(serialized_events))
sent_ephemeral_counter.labels(service.id).inc(len(ephemeral))
sent_todevice_counter.labels(service.id).inc(len(to_device_messages))
self.sent_transactions_counter.labels(service.id).inc()
self.sent_events_counter.labels(service.id).inc(len(serialized_events))
self.sent_ephemeral_counter.labels(service.id).inc(len(ephemeral))
self.sent_todevice_counter.labels(service.id).inc(len(to_device_messages))
return True
except CodeMessageException as e:
logger.warning(
@@ -417,7 +428,7 @@ class ApplicationServiceApi(SimpleHttpClient):
ex.args,
exc_info=logger.isEnabledFor(logging.DEBUG),
)
failed_transactions_counter.labels(service.id).inc()
self.failed_transactions_counter.labels(service.id).inc()
return False
async def claim_client_keys(
@@ -555,9 +566,6 @@ class ApplicationServiceApi(SimpleHttpClient):
)
and service.is_interested_in_user(e.state_key)
),
# Appservices are considered 'trusted' by the admin and should have
# applicable metadata on their events.
include_admin_metadata=True,
),
)
for e in events

View File

@@ -909,10 +909,7 @@ class RootConfig:
def read_config_files(config_files: Iterable[str]) -> Dict[str, Any]:
"""Read the config files and shallowly merge them into a dict.
Successive configurations are shallowly merged into ones provided earlier,
i.e., entirely replacing top-level sections of the configuration.
"""Read the config files into a dict
Args:
config_files: A list of the config files to read

View File

@@ -23,17 +23,7 @@ from typing import Any
from synapse.types import JsonDict
from ._base import Config, ConfigError, read_file
CONFLICTING_RECAPTCHA_PRIVATE_KEY_OPTS_ERROR = """\
You have configured both `recaptcha_private_key` and
`recaptcha_private_key_path`. These are mutually incompatible.
"""
CONFLICTING_RECAPTCHA_PUBLIC_KEY_OPTS_ERROR = """\
You have configured both `recaptcha_public_key` and `recaptcha_public_key_path`.
These are mutually incompatible.
"""
from ._base import Config, ConfigError
class CaptchaConfig(Config):
@@ -48,13 +38,6 @@ class CaptchaConfig(Config):
"Config options that expect an in-line secret as value are disabled",
("recaptcha_private_key",),
)
recaptcha_private_key_path = config.get("recaptcha_private_key_path")
if recaptcha_private_key_path:
if recaptcha_private_key:
raise ConfigError(CONFLICTING_RECAPTCHA_PRIVATE_KEY_OPTS_ERROR)
recaptcha_private_key = read_file(
recaptcha_private_key_path, ("recaptcha_private_key_path",)
).strip()
if recaptcha_private_key is not None and not isinstance(
recaptcha_private_key, str
):
@@ -67,13 +50,6 @@ class CaptchaConfig(Config):
"Config options that expect an in-line secret as value are disabled",
("recaptcha_public_key",),
)
recaptcha_public_key_path = config.get("recaptcha_public_key_path")
if recaptcha_public_key_path:
if recaptcha_public_key:
raise ConfigError(CONFLICTING_RECAPTCHA_PUBLIC_KEY_OPTS_ERROR)
recaptcha_public_key = read_file(
recaptcha_public_key_path, ("recaptcha_public_key_path",)
).strip()
if recaptcha_public_key is not None and not isinstance(
recaptcha_public_key, str
):

View File

@@ -42,9 +42,6 @@ class CasConfig(Config):
self.cas_enabled = cas_config and cas_config.get("enabled", True)
if self.cas_enabled:
if not isinstance(cas_config, dict):
raise ConfigError("Must be a dictionary", ("cas_config",))
self.cas_server_url = cas_config["server_url"]
# TODO Update this to a _synapse URL.

View File

@@ -561,23 +561,11 @@ class ExperimentalConfig(Config):
# MSC4076: Add `disable_badge_count`` to pusher configuration
self.msc4076_enabled: bool = experimental.get("msc4076_enabled", False)
# MSC4277: Harmonizing the reporting endpoints
#
# If enabled, ignore the score parameter and respond with HTTP 200 on
# reporting requests regardless of the subject's existence.
self.msc4277_enabled: bool = experimental.get("msc4277_enabled", False)
# MSC4235: Add `via` param to hierarchy endpoint
self.msc4235_enabled: bool = experimental.get("msc4235_enabled", False)
# MSC4263: Preventing MXID enumeration via key queries
self.msc4263_limit_key_queries_to_users_who_share_rooms = experimental.get(
"msc4263_limit_key_queries_to_users_who_share_rooms",
False,
)
# MSC4267: Automatically forgetting rooms on leave
self.msc4267_enabled: bool = experimental.get("msc4267_enabled", False)
# MSC4155: Invite filtering
self.msc4155_enabled: bool = experimental.get("msc4155_enabled", False)

View File

@@ -212,14 +212,11 @@ class KeyConfig(Config):
"Config options that expect an in-line secret as value are disabled",
("form_secret",),
)
if form_secret is not None and not isinstance(form_secret, str):
raise ConfigError("Config option must be a string", ("form_secret",))
form_secret_path = config.get("form_secret_path", None)
if form_secret_path:
if form_secret:
raise ConfigError(CONFLICTING_FORM_SECRET_OPTS_ERROR)
self.form_secret: Optional[str] = read_file(
self.form_secret = read_file(
form_secret_path, ("form_secret_path",)
).strip()
else:

View File

@@ -119,15 +119,6 @@ def parse_thumbnail_requirements(
}
@attr.s(auto_attribs=True, slots=True, frozen=True)
class MediaUploadLimit:
"""A limit on the amount of data a user can upload in a given time
period."""
max_bytes: int
time_period_ms: int
class ContentRepositoryConfig(Config):
section = "media"
@@ -283,13 +274,6 @@ class ContentRepositoryConfig(Config):
self.enable_authenticated_media = config.get("enable_authenticated_media", True)
self.media_upload_limits: List[MediaUploadLimit] = []
for limit_config in config.get("media_upload_limits", []):
time_period_ms = self.parse_duration(limit_config["time_period"])
max_bytes = self.parse_size(limit_config["max_size"])
self.media_upload_limits.append(MediaUploadLimit(max_bytes, time_period_ms))
def generate_config_section(self, data_dir_path: str, **kwargs: Any) -> str:
assert data_dir_path is not None
media_store = os.path.join(data_dir_path, "media_store")

View File

@@ -85,4 +85,4 @@ class RoomConfig(Config):
# When enabled, users will forget rooms when they leave them, either via a
# leave, kick or ban.
self.forget_on_leave: bool = config.get("forget_rooms_on_leave", False)
self.forget_on_leave = config.get("forget_rooms_on_leave", False)

View File

@@ -27,6 +27,8 @@ from typing import Any, Dict, List, Optional, Union
import attr
from synapse._pydantic_compat import (
BaseModel,
Extra,
StrictBool,
StrictInt,
StrictStr,
@@ -45,7 +47,6 @@ from synapse.config.server import (
parse_listener_def,
)
from synapse.types import JsonDict
from synapse.util.pydantic_models import ParseModel
_DEPRECATED_WORKER_DUTY_OPTION_USED = """
The '%s' configuration option is deprecated and will be removed in a future
@@ -89,7 +90,30 @@ def _instance_to_list_converter(obj: Union[str, List[str]]) -> List[str]:
return obj
class InstanceTcpLocationConfig(ParseModel):
class ConfigModel(BaseModel):
"""A custom version of Pydantic's BaseModel which
- ignores unknown fields and
- does not allow fields to be overwritten after construction,
but otherwise uses Pydantic's default behaviour.
For now, ignore unknown fields. In the future, we could change this so that unknown
config values cause a ValidationError, provided the error messages are meaningful to
server operators.
Subclassing in this way is recommended by
https://pydantic-docs.helpmanual.io/usage/model_config/#change-behaviour-globally
"""
class Config:
# By default, ignore fields that we don't recognise.
extra = Extra.ignore
# By default, don't allow fields to be reassigned after parsing.
allow_mutation = False
class InstanceTcpLocationConfig(ConfigModel):
"""The host and port to talk to an instance via HTTP replication."""
host: StrictStr
@@ -105,7 +129,7 @@ class InstanceTcpLocationConfig(ParseModel):
return f"{self.host}:{self.port}"
class InstanceUnixLocationConfig(ParseModel):
class InstanceUnixLocationConfig(ConfigModel):
"""The socket file to talk to an instance via HTTP replication."""
path: StrictStr
@@ -238,16 +262,10 @@ class WorkerConfig(Config):
if worker_replication_secret_path:
if worker_replication_secret:
raise ConfigError(CONFLICTING_WORKER_REPLICATION_SECRET_OPTS_ERROR)
self.worker_replication_secret: Optional[str] = read_file(
self.worker_replication_secret = read_file(
worker_replication_secret_path, ("worker_replication_secret_path",)
).strip()
else:
if worker_replication_secret is not None and not isinstance(
worker_replication_secret, str
):
raise ConfigError(
"Config option must be a string", ("worker_replication_secret",)
)
self.worker_replication_secret = worker_replication_secret
self.worker_name = config.get("worker_name", self.worker_app)

View File

@@ -208,6 +208,7 @@ class EventBase(metaclass=abc.ABCMeta):
depth: DictProperty[int] = DictProperty("depth")
content: DictProperty[JsonDict] = DictProperty("content")
hashes: DictProperty[Dict[str, str]] = DictProperty("hashes")
origin: DictProperty[str] = DictProperty("origin")
origin_server_ts: DictProperty[int] = DictProperty("origin_server_ts")
room_id: DictProperty[str] = DictProperty("room_id")
sender: DictProperty[str] = DictProperty("sender")

View File

@@ -302,8 +302,8 @@ def create_local_event_from_event_dict(
event_dict: JsonDict,
internal_metadata_dict: Optional[JsonDict] = None,
) -> EventBase:
"""Takes a fully formed event dict, ensuring that fields like
`origin_server_ts` have correct values for a locally produced event,
"""Takes a fully formed event dict, ensuring that fields like `origin`
and `origin_server_ts` have correct values for a locally produced event,
then signs and hashes it.
"""
@@ -319,6 +319,7 @@ def create_local_event_from_event_dict(
if format_version == EventFormatVersions.ROOM_V1_V2:
event_dict["event_id"] = _create_event_id(clock, hostname)
event_dict["origin"] = hostname
event_dict.setdefault("origin_server_ts", time_now)
event_dict.setdefault("unsigned", {})

View File

@@ -421,21 +421,11 @@ class SerializeEventConfig:
# False, that state will be removed from the event before it is returned.
# Otherwise, it will be kept.
include_stripped_room_state: bool = False
# When True, sets unsigned fields to help clients identify events which
# only server admins can see through other configuration. For example,
# whether an event was soft failed by the server.
include_admin_metadata: bool = False
_DEFAULT_SERIALIZE_EVENT_CONFIG = SerializeEventConfig()
def make_config_for_admin(existing: SerializeEventConfig) -> SerializeEventConfig:
# Set the options which are only available to server admins,
# and copy the rest.
return attr.evolve(existing, include_admin_metadata=True)
def serialize_event(
e: Union[JsonDict, EventBase],
time_now_ms: int,
@@ -538,9 +528,6 @@ def serialize_event(
d["content"] = dict(d["content"])
d["content"]["redacts"] = e.redacts
if config.include_admin_metadata and e.internal_metadata.is_soft_failed():
d["unsigned"]["io.element.synapse.soft_failed"] = True
only_event_fields = config.only_event_fields
if only_event_fields:
if not isinstance(only_event_fields, list) or not all(
@@ -561,7 +548,6 @@ class EventClientSerializer:
def __init__(self, hs: "HomeServer") -> None:
self._store = hs.get_datastores().main
self._auth = hs.get_auth()
self._add_extra_fields_to_unsigned_client_event_callbacks: List[
ADD_EXTRA_FIELDS_TO_UNSIGNED_CLIENT_EVENT_CALLBACK
] = []
@@ -590,15 +576,6 @@ class EventClientSerializer:
if not isinstance(event, EventBase):
return event
# Force-enable server admin metadata because the only time an event with
# relevant metadata will be when the admin requested it via their admin
# client config account data. Also, it's "just" some `unsigned` fields, so
# shouldn't cause much in terms of problems to downstream consumers.
if config.requester is not None and await self._auth.is_server_admin(
config.requester
):
config = make_config_for_admin(config)
serialized_event = serialize_event(event, time_now, config=config)
new_unsigned = {}

View File

@@ -67,6 +67,7 @@ class EventValidator:
"auth_events",
"content",
"hashes",
"origin",
"prev_events",
"sender",
"type",
@@ -76,6 +77,13 @@ class EventValidator:
if k not in event:
raise SynapseError(400, "Event does not have key %s" % (k,))
# Check that the following keys have string values
event_strings = ["origin"]
for s in event_strings:
if not isinstance(getattr(event, s), str):
raise SynapseError(400, "'%s' not a string type" % (s,))
# Depending on the room version, ensure the data is spec compliant JSON.
if event.room_version.strict_canonicaljson:
validate_canonicaljson(event.get_pdu_json())

View File

@@ -322,7 +322,8 @@ def event_from_pdu_json(pdu_json: JsonDict, room_version: RoomVersion) -> EventB
SynapseError: if the pdu is missing required fields or is otherwise
not a valid matrix event
"""
# we could probably enforce a bunch of other fields here (room_id, sender, etc.)
# we could probably enforce a bunch of other fields here (room_id, sender,
# origin, etc etc)
assert_params_in_dict(pdu_json, ("type", "depth"))
# Strip any unauthorized values from "unsigned" if they exist

View File

@@ -85,8 +85,6 @@ if TYPE_CHECKING:
logger = logging.getLogger(__name__)
sent_queries_counter = Counter("synapse_federation_client_sent_queries", "", ["type"])
PDU_RETRY_TIME_MS = 1 * 60 * 1000
@@ -145,6 +143,7 @@ class FederationClient(FederationBase):
self._get_pdu_cache: ExpiringCache[str, Tuple[EventBase, str]] = ExpiringCache(
cache_name="get_pdu_cache",
clock=self._clock,
cache_manager=hs.get_cache_manager(),
max_len=1000,
expiry_ms=120 * 1000,
reset_expiry_on_get=False,
@@ -163,11 +162,19 @@ class FederationClient(FederationBase):
] = ExpiringCache(
cache_name="get_room_hierarchy_cache",
clock=self._clock,
cache_manager=hs.get_cache_manager(),
max_len=1000,
expiry_ms=5 * 60 * 1000,
reset_expiry_on_get=False,
)
self.sent_queries_counter = Counter(
"synapse_federation_client_sent_queries",
"",
["type"],
registry=hs.metrics_collector_registry,
)
def _clear_tried_cache(self) -> None:
"""Clear pdu_destination_tried cache"""
now = self._clock.time_msec()
@@ -207,7 +214,7 @@ class FederationClient(FederationBase):
Returns:
The JSON object from the response
"""
sent_queries_counter.labels(query_type).inc()
self.sent_queries_counter.labels(query_type).inc()
return await self.transport_layer.make_query(
destination,
@@ -229,7 +236,7 @@ class FederationClient(FederationBase):
Returns:
The JSON object from the response
"""
sent_queries_counter.labels("client_device_keys").inc()
self.sent_queries_counter.labels("client_device_keys").inc()
return await self.transport_layer.query_client_keys(
destination, content, timeout
)
@@ -240,7 +247,7 @@ class FederationClient(FederationBase):
"""Query the device keys for a list of user ids hosted on a remote
server.
"""
sent_queries_counter.labels("user_devices").inc()
self.sent_queries_counter.labels("user_devices").inc()
return await self.transport_layer.query_user_devices(
destination, user_id, timeout
)
@@ -262,7 +269,7 @@ class FederationClient(FederationBase):
Returns:
The JSON object from the response
"""
sent_queries_counter.labels("client_one_time_keys").inc()
self.sent_queries_counter.labels("client_one_time_keys").inc()
# Convert the query with counts into a stable and unstable query and check
# if attempting to claim more than 1 OTK.

View File

@@ -85,6 +85,7 @@ from synapse.logging.opentracing import (
from synapse.metrics.background_process_metrics import wrap_as_background_process
from synapse.replication.http.federation import (
ReplicationFederationSendEduRestServlet,
ReplicationGetQueryRestServlet,
)
from synapse.storage.databases.main.lock import Lock
from synapse.storage.databases.main.roommember import extract_heroes_from_room_summary
@@ -104,25 +105,6 @@ TRANSACTION_CONCURRENCY_LIMIT = 10
logger = logging.getLogger(__name__)
received_pdus_counter = Counter("synapse_federation_server_received_pdus", "")
received_edus_counter = Counter("synapse_federation_server_received_edus", "")
received_queries_counter = Counter(
"synapse_federation_server_received_queries", "", ["type"]
)
pdu_process_time = Histogram(
"synapse_federation_server_pdu_process_time",
"Time taken to process an event",
)
last_pdu_ts_metric = Gauge(
"synapse_federation_last_received_pdu_time",
"The timestamp of the last PDU which was successfully received from the given domain",
labelnames=("server_name",),
)
# The name of the lock to use when process events in a room received over
# federation.
@@ -159,7 +141,10 @@ class FederationServer(FederationBase):
# We cache results for transaction with the same ID
self._transaction_resp_cache: ResponseCache[Tuple[str, str]] = ResponseCache(
hs.get_clock(), "fed_txn_handler", timeout_ms=30000
hs.get_clock(),
hs.get_cache_manager(),
"fed_txn_handler",
timeout_ms=30000,
)
self.transaction_actions = TransactionActions(self.store)
@@ -169,10 +154,18 @@ class FederationServer(FederationBase):
# We cache responses to state queries, as they take a while and often
# come in waves.
self._state_resp_cache: ResponseCache[Tuple[str, Optional[str]]] = (
ResponseCache(hs.get_clock(), "state_resp", timeout_ms=30000)
ResponseCache(
hs.get_clock(),
hs.get_cache_manager(),
"state_resp",
timeout_ms=30000,
)
)
self._state_ids_resp_cache: ResponseCache[Tuple[str, str]] = ResponseCache(
hs.get_clock(), "state_ids_resp", timeout_ms=30000
hs.get_clock(),
hs.get_cache_manager(),
"state_ids_resp",
timeout_ms=30000,
)
self._federation_metrics_domains = (
@@ -184,6 +177,38 @@ class FederationServer(FederationBase):
# Whether we have started handling old events in the staging area.
self._started_handling_of_staged_events = False
self.received_pdus_counter = Counter(
"synapse_federation_server_received_pdus",
"",
registry=hs.metrics_collector_registry,
)
self.received_edus_counter = Counter(
"synapse_federation_server_received_edus",
"",
registry=hs.metrics_collector_registry,
)
self.received_queries_counter = Counter(
"synapse_federation_server_received_queries",
"",
["type"],
registry=hs.metrics_collector_registry,
)
self.pdu_process_time = Histogram(
"synapse_federation_server_pdu_process_time",
"Time taken to process an event",
registry=hs.metrics_collector_registry,
)
self.last_pdu_ts_metric = Gauge(
"synapse_federation_last_received_pdu_time",
"The timestamp of the last PDU which was successfully received from the given domain",
labelnames=("server_name",),
registry=hs.metrics_collector_registry,
)
@wrap_as_background_process("_handle_old_staged_events")
async def _handle_old_staged_events(self) -> None:
"""Handle old staged events by fetching all rooms that have staged
@@ -423,7 +448,7 @@ class FederationServer(FederationBase):
report back to the sending server.
"""
received_pdus_counter.inc(len(transaction.pdus))
self.received_pdus_counter.inc(len(transaction.pdus))
origin_host, _ = parse_server_name(origin)
@@ -534,7 +559,7 @@ class FederationServer(FederationBase):
)
if newest_pdu_ts and origin in self._federation_metrics_domains:
last_pdu_ts_metric.labels(server_name=origin).set(newest_pdu_ts / 1000)
self.last_pdu_ts_metric.labels(server_name=origin).set(newest_pdu_ts / 1000)
return pdu_results
@@ -542,7 +567,7 @@ class FederationServer(FederationBase):
"""Process the EDUs in a received transaction."""
async def _process_edu(edu_dict: JsonDict) -> None:
received_edus_counter.inc()
self.received_edus_counter.inc()
edu = Edu(
origin=origin,
@@ -657,7 +682,7 @@ class FederationServer(FederationBase):
async def on_query_request(
self, query_type: str, args: Dict[str, str]
) -> Tuple[int, Dict[str, Any]]:
received_queries_counter.labels(query_type).inc()
self.received_queries_counter.labels(query_type).inc()
resp = await self.registry.on_query(query_type, args)
return 200, resp
@@ -1299,7 +1324,7 @@ class FederationServer(FederationBase):
origin, event.event_id
)
if received_ts is not None:
pdu_process_time.observe(
self.pdu_process_time.observe(
(self._clock.time_msec() - received_ts) / 1000
)
@@ -1379,6 +1404,7 @@ class FederationHandlerRegistry:
# and use them. However we have guards before we use them to ensure that
# we don't route to ourselves, and in monolith mode that will always be
# the case.
self._get_query_client = ReplicationGetQueryRestServlet.make_client(hs)
self._send_edu = ReplicationFederationSendEduRestServlet.make_client(hs)
self.edu_handlers: Dict[str, Callable[[str, dict], Awaitable[None]]] = {}
@@ -1467,6 +1493,10 @@ class FederationHandlerRegistry:
if handler:
return await handler(args)
# Check if we can route it somewhere else that isn't us
if self._instance_name == "master":
return await self._get_query_client(query_type=query_type, args=args)
# Uh oh, no handler! Let's raise an exception so the request returns an
# error.
logger.warning("No handler registered for query type %s", query_type)

View File

@@ -73,6 +73,7 @@ class FederationRemoteSendQueue(AbstractFederationSender):
def __init__(self, hs: "HomeServer"):
self.server_name = hs.hostname
self.clock = hs.get_clock()
self.metrics_collector_registry = hs.metrics_collector_registry
self.notifier = hs.get_notifier()
self.is_mine_id = hs.is_mine_id
self.is_mine_server_name = hs.is_mine_server_name
@@ -117,6 +118,7 @@ class FederationRemoteSendQueue(AbstractFederationSender):
"",
[],
lambda: len(queue),
registry=hs.metrics_collector_registry,
)
for queue_name in [
@@ -156,9 +158,7 @@ class FederationRemoteSendQueue(AbstractFederationSender):
def _clear_queue_before_pos(self, position_to_delete: int) -> None:
"""Clear all the queues from before a given position"""
with Measure(
self.clock, name="send_queue._clear", server_name=self.server_name
):
with Measure(self.clock, self.metrics_collector_registry, "send_queue._clear"):
# Delete things out of presence maps
keys = self.presence_destinations.keys()
i = self.presence_destinations.bisect_left(position_to_delete)

View File

@@ -186,15 +186,6 @@ if TYPE_CHECKING:
logger = logging.getLogger(__name__)
sent_pdus_destination_dist_count = Counter(
"synapse_federation_client_sent_pdu_destinations_count",
"Number of PDUs queued for sending to one or more destinations",
)
sent_pdus_destination_dist_total = Counter(
"synapse_federation_client_sent_pdu_destinations",
"Total number of PDUs queued for sending across all destinations",
)
# Time (in s) to wait before trying to wake up destinations that have
# catch-up outstanding.
@@ -378,6 +369,7 @@ class FederationSender(AbstractFederationSender):
self._storage_controllers = hs.get_storage_controllers()
self.clock = hs.get_clock()
self.metrics_collector_registry = hs.metrics_collector_registry
self.is_mine_id = hs.is_mine_id
self.is_mine_server_name = hs.is_mine_server_name
@@ -399,6 +391,7 @@ class FederationSender(AbstractFederationSender):
for d in self._per_destination_queues.values()
if d.transmission_loop_running
),
registry=hs.metrics_collector_registry,
)
LaterGauge(
@@ -408,6 +401,7 @@ class FederationSender(AbstractFederationSender):
lambda: sum(
d.pending_pdu_count() for d in self._per_destination_queues.values()
),
registry=hs.metrics_collector_registry,
)
LaterGauge(
"synapse_federation_transaction_queue_pending_edus",
@@ -416,6 +410,19 @@ class FederationSender(AbstractFederationSender):
lambda: sum(
d.pending_edu_count() for d in self._per_destination_queues.values()
),
registry=hs.metrics_collector_registry,
)
self.sent_pdus_destination_dist_count = Counter(
"synapse_federation_client_sent_pdu_destinations_count",
"Number of PDUs queued for sending to one or more destinations",
registry=hs.metrics_collector_registry,
)
self.sent_pdus_destination_dist_total = Counter(
"synapse_federation_client_sent_pdu_destinations",
"Total number of PDUs queued for sending across all destinations",
registry=hs.metrics_collector_registry,
)
self._is_processing = False
@@ -659,8 +666,8 @@ class FederationSender(AbstractFederationSender):
)
with Measure(
self.clock,
name="handle_room_events",
server_name=self.server_name,
self.metrics_collector_registry,
"handle_room_events",
):
for event in events:
await handle_event(event)
@@ -727,8 +734,8 @@ class FederationSender(AbstractFederationSender):
if not destinations:
return
sent_pdus_destination_dist_total.inc(len(destinations))
sent_pdus_destination_dist_count.inc()
self.sent_pdus_destination_dist_total.inc(len(destinations))
self.sent_pdus_destination_dist_count.inc()
assert pdu.internal_metadata.stream_ordering

View File

@@ -55,17 +55,6 @@ MAX_EDUS_PER_TRANSACTION = 100
logger = logging.getLogger(__name__)
sent_edus_counter = Counter(
"synapse_federation_client_sent_edus", "Total number of EDUs successfully sent"
)
sent_edus_by_type = Counter(
"synapse_federation_client_sent_edus_by_type",
"Number of sent EDUs successfully sent, by event type",
["type"],
)
# If the retry interval is larger than this then we enter "catchup" mode
CATCHUP_RETRY_INTERVAL = 60 * 60 * 1000
@@ -129,8 +118,6 @@ class PerDestinationQueue:
# The stream_ordering of the most recent PDU that was discarded due to
# being in catch-up mode.
# Can be set to zero if no PDU has been discarded since the last time
# we queried for new PDUs during catch-up.
self._catchup_last_skipped: int = 0
# Cache of the last successfully-transmitted stream ordering for this
@@ -166,6 +153,19 @@ class PerDestinationQueue:
# stream_id of last successfully sent device list update.
self._last_device_list_stream_id = 0
self.sent_edus_counter = Counter(
"synapse_federation_client_sent_edus",
"Total number of EDUs successfully sent",
registry=hs.metrics_collector_registry,
)
self.sent_edus_by_type = Counter(
"synapse_federation_client_sent_edus_by_type",
"Number of sent EDUs successfully sent, by event type",
["type"],
registry=hs.metrics_collector_registry,
)
def __str__(self) -> str:
return "PerDestinationQueue[%s]" % self._destination
@@ -363,9 +363,9 @@ class PerDestinationQueue:
)
sent_transactions_counter.inc()
sent_edus_counter.inc(len(pending_edus))
self.sent_edus_counter.inc(len(pending_edus))
for edu in pending_edus:
sent_edus_by_type.labels(edu.edu_type).inc()
self.sent_edus_by_type.labels(edu.edu_type).inc()
except NotRetryingDestination as e:
logger.debug(
@@ -464,18 +464,8 @@ class PerDestinationQueue:
# of a race condition, so we check that no new events have been
# skipped due to us being in catch-up mode
if (
self._catchup_last_skipped != 0
and self._catchup_last_skipped > last_successful_stream_ordering
):
if self._catchup_last_skipped > last_successful_stream_ordering:
# another event has been skipped because we were in catch-up mode
# As an exception to this case: we can hit this branch if the
# room has been purged whilst we have been looping.
# In that case we avoid hot-looping by resetting the 'catch-up skipped
# PDU' flag.
# Then if there is still no progress to be made at the next iteration,
# we can exit catch-up mode.
self._catchup_last_skipped = 0
continue
# we are done catching up!

View File

@@ -58,8 +58,11 @@ class TransactionManager:
"""
def __init__(self, hs: "synapse.server.HomeServer"):
self.server_name = hs.hostname # nb must be called this for @measure_func
self._server_name = hs.hostname
self.clock = hs.get_clock() # nb must be called this for @measure_func
self.metrics_collector_registry = (
hs.metrics_collector_registry
) # nb must be called this for @measure_func
self._store = hs.get_datastores().main
self._transaction_actions = TransactionActions(self._store)
self._transport_layer = hs.get_federation_transport_client()
@@ -116,7 +119,7 @@ class TransactionManager:
transaction = Transaction(
origin_server_ts=int(self.clock.time_msec()),
transaction_id=txn_id,
origin=self.server_name,
origin=self._server_name,
destination=destination,
pdus=[p.get_pdu_json() for p in pdus],
edus=[edu.get_dict() for edu in edus],

View File

@@ -68,18 +68,16 @@ if TYPE_CHECKING:
logger = logging.getLogger(__name__)
events_processed_counter = Counter("synapse_handlers_appservice_events_processed", "")
class ApplicationServicesHandler:
def __init__(self, hs: "HomeServer"):
self.server_name = hs.hostname
self.store = hs.get_datastores().main
self.is_mine_id = hs.is_mine_id
self.appservice_api = hs.get_application_service_api()
self.scheduler = hs.get_application_service_scheduler()
self.started_scheduler = False
self.clock = hs.get_clock()
self.metrics_collector_registry = hs.metrics_collector_registry
self.notify_appservices = hs.config.worker.should_notify_appservices
self.event_sources = hs.get_event_sources()
self._msc2409_to_device_messages_enabled = (
@@ -96,6 +94,12 @@ class ApplicationServicesHandler:
name="appservice_ephemeral_events"
)
self.events_processed_counter = Counter(
"synapse_handlers_appservice_events_processed",
"",
registry=hs.metrics_collector_registry,
)
def notify_interested_services(self, max_token: RoomStreamToken) -> None:
"""Notifies (pushes) all application services interested in this event.
@@ -122,7 +126,7 @@ class ApplicationServicesHandler:
@wrap_as_background_process("notify_interested_services")
async def _notify_interested_services(self, max_token: RoomStreamToken) -> None:
with Measure(
self.clock, name="notify_interested_services", server_name=self.server_name
self.clock, self.metrics_collector_registry, "notify_interested_services"
):
self.is_processing = True
try:
@@ -203,7 +207,7 @@ class ApplicationServicesHandler:
"appservice_sender"
).set(upper_bound)
events_processed_counter.inc(len(events))
self.events_processed_counter.inc(len(events))
event_processing_loop_room_count.labels("appservice_sender").inc(
len(events_by_room)
@@ -334,8 +338,8 @@ class ApplicationServicesHandler:
logger.debug("Checking interested services for %s", stream_key)
with Measure(
self.clock,
name="notify_interested_services_ephemeral",
server_name=self.server_name,
self.metrics_collector_registry,
"notify_interested_services_ephemeral",
):
for service in services:
if stream_key == StreamKeyType.TYPING:

View File

@@ -76,7 +76,7 @@ from synapse.storage.databases.main.registration import (
LoginTokenLookupResult,
LoginTokenReused,
)
from synapse.types import JsonDict, Requester, StrCollection, UserID
from synapse.types import JsonDict, Requester, UserID
from synapse.util import stringutils as stringutils
from synapse.util.async_helpers import delay_cancellation, maybe_awaitable
from synapse.util.msisdn import phone_number_to_msisdn
@@ -92,12 +92,6 @@ logger = logging.getLogger(__name__)
INVALID_USERNAME_OR_PASSWORD = "Invalid username or password"
invalid_login_token_counter = Counter(
"synapse_user_login_invalid_login_tokens",
"Counts the number of rejected m.login.token on /login",
["reason"],
)
def convert_client_dict_legacy_fields_to_identifier(
submission: JsonDict,
@@ -174,7 +168,6 @@ def login_id_phone_to_thirdparty(identifier: JsonDict) -> Dict[str, str]:
# Accept both "phone" and "number" as valid keys in m.id.phone
phone_number = identifier.get("phone", identifier["number"])
assert isinstance(phone_number, str)
# Convert user-provided phone number to a consistent representation
msisdn = phone_number_to_msisdn(identifier["country"], phone_number)
@@ -282,6 +275,13 @@ class AuthHandler:
self.msc3861_oauth_delegation_enabled = hs.config.experimental.msc3861.enabled
self.invalid_login_token_counter = Counter(
"synapse_user_login_invalid_login_tokens",
"Counts the number of rejected m.login.token on /login",
["reason"],
registry=hs.metrics_collector_registry,
)
async def validate_user_via_ui_auth(
self,
requester: Requester,
@@ -1478,11 +1478,11 @@ class AuthHandler:
try:
return await self.store.consume_login_token(login_token)
except LoginTokenExpired:
invalid_login_token_counter.labels("expired").inc()
self.invalid_login_token_counter.labels("expired").inc()
except LoginTokenReused:
invalid_login_token_counter.labels("reused").inc()
self.invalid_login_token_counter.labels("reused").inc()
except NotFoundError:
invalid_login_token_counter.labels("not found").inc()
self.invalid_login_token_counter.labels("not found").inc()
raise AuthError(403, "Invalid login token", errcode=Codes.FORBIDDEN)
@@ -1548,31 +1548,6 @@ class AuthHandler:
user_id, (token_id for _, token_id, _ in tokens_and_devices)
)
async def delete_access_tokens_for_devices(
self,
user_id: str,
device_ids: StrCollection,
) -> None:
"""Invalidate access tokens for the devices
Args:
user_id: ID of user the tokens belong to
device_ids: ID of device the tokens are associated with.
If None, tokens associated with any device (or no device) will
be deleted
"""
tokens_and_devices = await self.store.user_delete_access_tokens_for_devices(
user_id,
device_ids,
)
# see if any modules want to know about this
if self.password_auth_provider.on_logged_out_callbacks:
for token, _, device_id in tokens_and_devices:
await self.password_auth_provider.on_logged_out(
user_id=user_id, device_id=device_id, access_token=token
)
async def add_threepid(
self, user_id: str, medium: str, address: str, validated_at: int
) -> None:

View File

@@ -378,8 +378,7 @@ class CasHandler:
# Arbitrarily use the first attribute found.
display_name = cas_response.attributes.get(
self._cas_displayname_attribute, # type: ignore[arg-type]
[None],
self._cas_displayname_attribute, [None]
)[0]
return UserAttributes(localpart=localpart, display_name=display_name)

View File

@@ -54,11 +54,11 @@ logger = logging.getLogger(__name__)
class DelayedEventsHandler:
def __init__(self, hs: "HomeServer"):
self.server_name = hs.hostname
self._store = hs.get_datastores().main
self._storage_controllers = hs.get_storage_controllers()
self._config = hs.config
self._clock = hs.get_clock()
self._metrics_collector_registry = hs.metrics_collector_registry
self._event_creation_handler = hs.get_event_creation_handler()
self._room_member_handler = hs.get_room_member_handler()
@@ -161,7 +161,7 @@ class DelayedEventsHandler:
# Loop round handling deltas until we're up to date
while True:
with Measure(
self._clock, name="delayed_events_delta", server_name=self.server_name
self._clock, self._metrics_collector_registry, "delayed_events_delta"
):
room_max_stream_ordering = self._store.get_room_max_stream_ordering()
if self._event_pos == room_max_stream_ordering:

View File

@@ -88,7 +88,10 @@ class DeviceWorkerHandler:
device_list_updater: "DeviceListWorkerUpdater"
def __init__(self, hs: "HomeServer"):
self.clock = hs.get_clock()
self.clock = hs.get_clock() # nb must be called this for @measure_func
self.metrics_collector_registry = (
hs.metrics_collector_registry
) # nb must be called this for @measure_func
self.hs = hs
self.store = hs.get_datastores().main
self.notifier = hs.get_notifier()
@@ -526,8 +529,6 @@ class DeviceHandler(DeviceWorkerHandler):
def __init__(self, hs: "HomeServer"):
super().__init__(hs)
self.server_name = hs.hostname # nb must be called this for @measure_func
self.clock = hs.get_clock() # nb must be called this for @measure_func
self.federation_sender = hs.get_federation_sender()
self._account_data_handler = hs.get_account_data_handler()
self._storage_controllers = hs.get_storage_controllers()
@@ -673,12 +674,12 @@ class DeviceHandler(DeviceWorkerHandler):
except_device_id: optional device id which should not be deleted
"""
device_map = await self.store.get_devices_by_user(user_id)
device_ids = list(device_map)
if except_device_id is not None:
device_map.pop(except_device_id, None)
user_device_ids = device_map.keys()
await self.delete_devices(user_id, user_device_ids)
device_ids = [d for d in device_ids if d != except_device_id]
await self.delete_devices(user_id, device_ids)
async def delete_devices(self, user_id: str, device_ids: StrCollection) -> None:
async def delete_devices(self, user_id: str, device_ids: List[str]) -> None:
"""Delete several devices
Args:
@@ -697,10 +698,17 @@ class DeviceHandler(DeviceWorkerHandler):
else:
raise
# Delete data specific to each device. Not optimised as its an
# experimental MSC.
if self.hs.config.experimental.msc3890_enabled:
for device_id in device_ids:
# Delete data specific to each device. Not optimised as it is not
# considered as part of a critical path.
for device_id in device_ids:
await self._auth_handler.delete_access_tokens_for_user(
user_id, device_id=device_id
)
await self.store.delete_e2e_keys_by_device(
user_id=user_id, device_id=device_id
)
if self.hs.config.experimental.msc3890_enabled:
# Remove any local notification settings for this device in accordance
# with MSC3890.
await self._account_data_handler.remove_account_data_for_user(
@@ -708,13 +716,6 @@ class DeviceHandler(DeviceWorkerHandler):
f"org.matrix.msc3890.local_notification_settings.{device_id}",
)
# If we're deleting a lot of devices, a bunch of them may not have any
# to-device messages queued up. We filter those out to avoid scheduling
# unnecessary tasks.
devices_with_messages = await self.store.get_devices_with_messages(
user_id, device_ids
)
for device_id in devices_with_messages:
# Delete device messages asynchronously and in batches using the task scheduler
# We specify an upper stream id to avoid deleting non delivered messages
# if an user re-uses a device ID.
@@ -728,10 +729,6 @@ class DeviceHandler(DeviceWorkerHandler):
},
)
await self._auth_handler.delete_access_tokens_for_devices(
user_id, device_ids=device_ids
)
# Pushers are deleted after `delete_access_tokens_for_user` is called so that
# modules using `on_logged_out` hook can use them if needed.
await self.hs.get_pusherpool().remove_pushers_by_devices(user_id, device_ids)
@@ -825,11 +822,10 @@ class DeviceHandler(DeviceWorkerHandler):
# This should only happen if there are no updates, so we bail.
return
if logger.isEnabledFor(logging.DEBUG):
for device_id in device_ids:
logger.debug(
"Notifying about update %r/%r, ID: %r", user_id, device_id, position
)
for device_id in device_ids:
logger.debug(
"Notifying about update %r/%r, ID: %r", user_id, device_id, position
)
# specify the user ID too since the user should always get their own device list
# updates, even if they aren't in any rooms.
@@ -929,6 +925,9 @@ class DeviceHandler(DeviceWorkerHandler):
# can't call self.delete_device because that will clobber the
# access token so call the storage layer directly
await self.store.delete_devices(user_id, [old_device_id])
await self.store.delete_e2e_keys_by_device(
user_id=user_id, device_id=old_device_id
)
# tell everyone that the old device is gone and that the dehydrated
# device has a new display name
@@ -950,6 +949,7 @@ class DeviceHandler(DeviceWorkerHandler):
raise errors.NotFoundError()
await self.delete_devices(user_id, [device_id])
await self.store.delete_e2e_keys_by_device(user_id=user_id, device_id=device_id)
@wrap_as_background_process("_handle_new_device_update_async")
async def _handle_new_device_update_async(self) -> None:
@@ -1217,8 +1217,7 @@ class DeviceListUpdater(DeviceListWorkerUpdater):
def __init__(self, hs: "HomeServer", device_handler: DeviceHandler):
self.store = hs.get_datastores().main
self.federation = hs.get_federation_client()
self.server_name = hs.hostname # nb must be called this for @measure_func
self.clock = hs.get_clock() # nb must be called this for @measure_func
self.clock = hs.get_clock()
self.device_handler = device_handler
self._notifier = hs.get_notifier()
@@ -1236,6 +1235,7 @@ class DeviceListUpdater(DeviceListWorkerUpdater):
self._seen_updates: ExpiringCache[str, Set[str]] = ExpiringCache(
cache_name="device_update_edu",
clock=self.clock,
cache_manager=hs.get_cache_manager(),
max_len=10000,
expiry_ms=30 * 60 * 1000,
iterable=True,

Some files were not shown because too many files have changed in this diff Show More