Fixup logcontexts after replication PR. (#19146)
Some checks are pending
Build docker images / Build and push image for linux/amd64 (push) Waiting to run
Build docker images / Build and push image for linux/arm64 (push) Waiting to run
Build docker images / Push merged images to docker.io/matrixdotorg/synapse (push) Blocked by required conditions
Build docker images / Push merged images to ghcr.io/element-hq/synapse (push) Blocked by required conditions
Deploy the documentation / Calculate variables for GitHub Pages deployment (push) Waiting to run
Deploy the documentation / GitHub Pages (push) Blocked by required conditions
Build release artifacts / Calculate list of debian distros (push) Waiting to run
Build release artifacts / Build .deb packages (push) Blocked by required conditions
Build release artifacts / Build wheels on macos-14 (push) Waiting to run
Build release artifacts / Build wheels on macos-15-intel (push) Waiting to run
Build release artifacts / Build wheels on ubuntu-24.04 (push) Waiting to run
Build release artifacts / Build wheels on ubuntu-24.04-arm (push) Waiting to run
Build release artifacts / Build sdist (push) Waiting to run
Build release artifacts / Attach assets to release (push) Blocked by required conditions
Schema / Ensure Synapse config schema is valid (push) Waiting to run
Schema / Ensure generated documentation is up-to-date (push) Waiting to run
Tests / lint-crlf (push) Waiting to run
Tests / lint (push) Blocked by required conditions
Tests / Typechecking (push) Blocked by required conditions
Tests / changes (push) Waiting to run
Tests / check-sampleconfig (push) Blocked by required conditions
Tests / check-schema-delta (push) Blocked by required conditions
Tests / check-lockfile (push) Waiting to run
Tests / lint-newsfile (push) Waiting to run
Tests / lint-clippy (push) Blocked by required conditions
Tests / lint-clippy-nightly (push) Blocked by required conditions
Tests / lint-rust (push) Blocked by required conditions
Tests / lint-rustfmt (push) Blocked by required conditions
Tests / lint-readme (push) Blocked by required conditions
Tests / linting-done (push) Blocked by required conditions
Tests / calculate-test-jobs (push) Blocked by required conditions
Tests / trial (push) Blocked by required conditions
Tests / trial-olddeps (push) Blocked by required conditions
Tests / trial-pypy (all, pypy-3.10) (push) Blocked by required conditions
Tests / sytest (push) Blocked by required conditions
Tests / export-data (push) Blocked by required conditions
Tests / portdb (13, 3.10) (push) Blocked by required conditions
Tests / portdb (17, 3.14) (push) Blocked by required conditions
Tests / complement (monolith, Postgres) (push) Blocked by required conditions
Tests / complement (monolith, SQLite) (push) Blocked by required conditions
Tests / complement (workers, Postgres) (push) Blocked by required conditions
Tests / cargo-test (push) Blocked by required conditions
Tests / cargo-bench (push) Blocked by required conditions
Tests / tests-done (push) Blocked by required conditions

Fixes logcontext leaks introduced in #19138.
This commit is contained in:
Erik Johnston 2025-11-05 15:38:14 +00:00 committed by GitHub
parent d3ffd04f66
commit 6790312831
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 32 additions and 25 deletions

1
changelog.d/19146.misc Normal file
View file

@ -0,0 +1 @@
Minor speed up of processing of inbound replication.

View file

@ -1029,7 +1029,8 @@ class DeferredEvent:
def set(self) -> None:
if not self._deferred.called:
self._deferred.callback(None)
with PreserveLoggingContext():
self._deferred.callback(None)
def clear(self) -> None:
if self._deferred.called:
@ -1042,26 +1043,15 @@ class DeferredEvent:
if self.is_set():
return True
# Create a deferred that gets called in N seconds
sleep_deferred: "defer.Deferred[None]" = defer.Deferred()
call = self._clock.call_later(
timeout_seconds,
sleep_deferred.callback,
None,
)
try:
await make_deferred_yieldable(
defer.DeferredList(
[sleep_deferred, self._deferred],
fireOnOneCallback=True,
fireOnOneErrback=True,
consumeErrors=True,
timeout_deferred(
deferred=stop_cancellation(self._deferred),
timeout=timeout_seconds,
clock=self._clock,
)
)
finally:
# Cancel the sleep if we were woken up
if call.active():
call.cancel()
except defer.TimeoutError:
pass
return self.is_set()

View file

@ -25,6 +25,8 @@ from typing import (
TypeVar,
)
from twisted.internet import defer
from synapse.util.async_helpers import DeferredEvent
from synapse.util.constants import MILLISECONDS_PER_SECOND
@ -110,6 +112,8 @@ class BackgroundQueue(Generic[T]):
item = self._queue.popleft()
try:
await self._callback(item)
except defer.CancelledError:
raise
except Exception:
logger.exception("Error processing background queue item")

View file

@ -18,11 +18,12 @@ from unittest.mock import Mock
from twisted.internet.defer import Deferred
from twisted.internet.testing import MemoryReactor
from synapse.logging.context import PreserveLoggingContext, make_deferred_yieldable
from synapse.server import HomeServer
from synapse.util.background_queue import BackgroundQueue
from synapse.util.clock import Clock
from tests.unittest import HomeserverTestCase
from tests.unittest import HomeserverTestCase, logcontext_clean
class BackgroundQueueTests(HomeserverTestCase):
@ -38,11 +39,14 @@ class BackgroundQueueTests(HomeserverTestCase):
timeout_ms=1000,
)
@logcontext_clean
def test_simple_call(self) -> None:
"""Test that items added to the queue are processed."""
# Register a deferred to be the return value of the callback.
callback_result_deferred: Deferred[None] = Deferred()
self._process_item_mock.side_effect = callback_result_deferred
self._process_item_mock.side_effect = lambda _: make_deferred_yieldable(
callback_result_deferred
)
# Adding an item should cause the callback to be invoked.
self.queue.add(1)
@ -57,16 +61,20 @@ class BackgroundQueueTests(HomeserverTestCase):
# Once the first callback completes, the second item should be
# processed.
callback_result_deferred.callback(None)
with PreserveLoggingContext():
callback_result_deferred.callback(None)
self._process_item_mock.assert_called_once_with(2)
@logcontext_clean
def test_timeout(self) -> None:
"""Test that the background process wakes up if its idle, and that it
times out after being idle."""
# Register a deferred to be the return value of the callback.
callback_result_deferred: Deferred[None] = Deferred()
self._process_item_mock.side_effect = callback_result_deferred
self._process_item_mock.side_effect = lambda _: make_deferred_yieldable(
callback_result_deferred
)
# Adding an item should cause the callback to be invoked.
self.queue.add(1)
@ -75,7 +83,8 @@ class BackgroundQueueTests(HomeserverTestCase):
self._process_item_mock.reset_mock()
# Let the callback complete.
callback_result_deferred.callback(None)
with PreserveLoggingContext():
callback_result_deferred.callback(None)
# Advance the clock by less than the timeout, and add another item.
self.reactor.advance(0.5)
@ -84,12 +93,15 @@ class BackgroundQueueTests(HomeserverTestCase):
# The callback should be invoked again.
callback_result_deferred = Deferred()
self._process_item_mock.side_effect = callback_result_deferred
self._process_item_mock.side_effect = lambda _: make_deferred_yieldable(
callback_result_deferred
)
self._process_item_mock.assert_called_once_with(2)
self._process_item_mock.reset_mock()
# Let the callback complete.
callback_result_deferred.callback(None)
with PreserveLoggingContext():
callback_result_deferred.callback(None)
# Advance the clock by more than the timeout.
self.reactor.advance(1.5)