Fix catchup-on-reconnect for the Federation Stream (#7374)

looks like we managed to break this during the refactorathon.
This commit is contained in:
Richard van der Hoff 2020-05-05 14:15:57 +01:00 committed by GitHub
parent 8123b2f909
commit d5aa7d93ed
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 158 additions and 48 deletions

View file

@ -80,7 +80,7 @@ class ReplicationStreamer(object):
for stream in STREAMS_MAP.values():
if stream == FederationStream and hs.config.send_federation:
# We only support federation stream if federation sending
# hase been disabled on the master.
# has been disabled on the master.
continue
self.streams.append(stream(hs))

View file

@ -104,7 +104,8 @@ class Stream(object):
implemented by subclasses.
current_token_function is called to get the current token of the underlying
stream.
stream. It is only meaningful on the process that is the source of the
replication stream (ie, usually the master).
update_function is called to get updates for this stream between a pair of
stream tokens. See the UpdateFunction type definition for more info.

View file

@ -15,7 +15,7 @@
# limitations under the License.
from collections import namedtuple
from synapse.replication.tcp.streams._base import Stream, db_query_to_update_function
from synapse.replication.tcp.streams._base import Stream, make_http_update_function
class FederationStream(Stream):
@ -35,21 +35,33 @@ class FederationStream(Stream):
ROW_TYPE = FederationStreamRow
def __init__(self, hs):
# Not all synapse instances will have a federation sender instance,
# whether that's a `FederationSender` or a `FederationRemoteSendQueue`,
# so we stub the stream out when that is the case.
if hs.config.worker_app is None or hs.should_send_federation():
if hs.config.worker_app is None:
# master process: get updates from the FederationRemoteSendQueue.
# (if the master is configured to send federation itself, federation_sender
# will be a real FederationSender, which has stubs for current_token and
# get_replication_rows.)
federation_sender = hs.get_federation_sender()
current_token = federation_sender.get_current_token
update_function = db_query_to_update_function(
federation_sender.get_replication_rows
)
update_function = federation_sender.get_replication_rows
elif hs.should_send_federation():
# federation sender: Query master process
update_function = make_http_update_function(hs, self.NAME)
current_token = self._stub_current_token
else:
current_token = lambda: 0
# other worker: stub out the update function (we're not interested in
# any updates so when we get a POSITION we do nothing)
update_function = self._stub_update_function
current_token = self._stub_current_token
super().__init__(hs.get_instance_name(), current_token, update_function)
@staticmethod
def _stub_current_token():
# dummy current-token method for use on workers
return 0
@staticmethod
async def _stub_update_function(instance_name, from_token, upto_token, limit):
return [], upto_token, False