From f69c651dabfed8d0127e40109184e88093a2cff9 Mon Sep 17 00:00:00 2001 From: Coding Assistant Date: Fri, 22 May 2026 11:17:00 +0100 Subject: [PATCH] fix: prevent replication stream from skipping local writes after other writer advance In Stream.get_updates(), the early-return path (last_token >= minimal_local_current_token) was advancing last_token to current_token. In a multi-writer setup, current_token (via get_current_token_for_writer) can be inflated by other writers' positions (via advance() -> _add_persisted_position -> _max_position_of_local_instance). This caused last_token to jump past the local writer's actual position, silently dropping subsequent local writes. Fix: advance last_token to minimal_local_current_token() instead of current_token. This ensures last_token never exceeds the local writer's actual persisted position, so subsequent local writes are always correctly detected and sent as RDATA. --- synapse/replication/tcp/streams/_base.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/synapse/replication/tcp/streams/_base.py b/synapse/replication/tcp/streams/_base.py index a73f767add..ffe2436c90 100644 --- a/synapse/replication/tcp/streams/_base.py +++ b/synapse/replication/tcp/streams/_base.py @@ -178,8 +178,14 @@ class Stream: # If the minimum current token for the local instance is less than or # equal to the last thing we published, we know that there are no # updates. + # + # We only advance last_token to minimal_local_current_token() rather + # than current_token. current_token may be inflated by other writers' + # positions (via advance()), and jumping last_token past the local + # writer's actual position would cause subsequent local writes to be + # silently dropped by the early return on the next call. if self.last_token >= self.minimal_local_current_token(): - self.last_token = current_token + self.last_token = self.minimal_local_current_token() return [], current_token, False updates, current_token, limited = await self.get_updates_since(