Skip to content

Commit e27d253

Browse files
fix: Always recheck /messages pagination data if a backfill might have been needed (#28)
1 parent 6197776 commit e27d253

2 files changed

Lines changed: 34 additions & 37 deletions

File tree

synapse/handlers/federation.py

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ def __init__(self, hs: "HomeServer"):
210210
@tag_args
211211
async def maybe_backfill(
212212
self, room_id: str, current_depth: int, limit: int, record_time: bool = True
213-
) -> bool:
213+
) -> None:
214214
"""Checks the database to see if we should backfill before paginating,
215215
and if so do.
216216
@@ -224,8 +224,6 @@ async def maybe_backfill(
224224
should back paginate.
225225
record_time: Whether to record the time it takes to backfill.
226226
227-
Returns:
228-
True if we actually tried to backfill something, otherwise False.
229227
"""
230228
# Starting the processing time here so we can include the room backfill
231229
# linearizer lock queue in the timing
@@ -251,7 +249,7 @@ async def _maybe_backfill_inner(
251249
limit: int,
252250
*,
253251
processing_start_time: Optional[int],
254-
) -> bool:
252+
) -> None:
255253
"""
256254
Checks whether the `current_depth` is at or approaching any backfill
257255
points in the room and if so, will backfill. We only care about
@@ -325,7 +323,7 @@ async def _maybe_backfill_inner(
325323
limit=1,
326324
)
327325
if not have_later_backfill_points:
328-
return False
326+
return None
329327

330328
logger.debug(
331329
"_maybe_backfill_inner: all backfill points are *after* current depth. Trying again with later backfill points."
@@ -345,15 +343,15 @@ async def _maybe_backfill_inner(
345343
)
346344
# We return `False` because we're backfilling in the background and there is
347345
# no new events immediately for the caller to know about yet.
348-
return False
346+
return None
349347

350348
# Even after recursing with `MAX_DEPTH`, we didn't find any
351349
# backward extremities to backfill from.
352350
if not sorted_backfill_points:
353351
logger.debug(
354-
"_maybe_backfill_inner: Not backfilling as no backward extremeties found."
352+
"_maybe_backfill_inner: Not backfilling as no backward extremities found."
355353
)
356-
return False
354+
return None
357355

358356
# If we're approaching an extremity we trigger a backfill, otherwise we
359357
# no-op.
@@ -372,7 +370,7 @@ async def _maybe_backfill_inner(
372370
current_depth,
373371
limit,
374372
)
375-
return False
373+
return None
376374

377375
# For performance's sake, we only want to paginate from a particular extremity
378376
# if we can actually see the events we'll get. Otherwise, we'd just spend a lot
@@ -440,7 +438,7 @@ async def _maybe_backfill_inner(
440438
logger.debug(
441439
"_maybe_backfill_inner: found no extremities which would be visible"
442440
)
443-
return False
441+
return None
444442

445443
logger.debug(
446444
"_maybe_backfill_inner: extremities_to_request %s", extremities_to_request
@@ -463,7 +461,7 @@ async def _maybe_backfill_inner(
463461
)
464462
)
465463

466-
async def try_backfill(domains: StrCollection) -> bool:
464+
async def try_backfill(domains: StrCollection) -> None:
467465
# TODO: Should we try multiple of these at a time?
468466

469467
# Number of contacted remote homeservers that have denied our backfill
@@ -486,7 +484,7 @@ async def try_backfill(domains: StrCollection) -> bool:
486484
# If this succeeded then we probably already have the
487485
# appropriate stuff.
488486
# TODO: We can probably do something more intelligent here.
489-
return True
487+
return None
490488
except NotRetryingDestination as e:
491489
logger.info("_maybe_backfill_inner: %s", e)
492490
continue
@@ -510,7 +508,7 @@ async def try_backfill(domains: StrCollection) -> bool:
510508
)
511509
denied_count += 1
512510
if denied_count >= max_denied_count:
513-
return False
511+
return None
514512
continue
515513

516514
logger.info("Failed to backfill from %s because %s", dom, e)
@@ -526,7 +524,7 @@ async def try_backfill(domains: StrCollection) -> bool:
526524
)
527525
denied_count += 1
528526
if denied_count >= max_denied_count:
529-
return False
527+
return None
530528
continue
531529

532530
logger.info("Failed to backfill from %s because %s", dom, e)
@@ -538,7 +536,7 @@ async def try_backfill(domains: StrCollection) -> bool:
538536
logger.exception("Failed to backfill from %s because %s", dom, e)
539537
continue
540538

541-
return False
539+
return None
542540

543541
# If we have the `processing_start_time`, then we can make an
544542
# observation. We wouldn't have the `processing_start_time` in the case
@@ -550,14 +548,9 @@ async def try_backfill(domains: StrCollection) -> bool:
550548
(processing_end_time - processing_start_time) / 1000
551549
)
552550

553-
success = await try_backfill(likely_domains)
554-
if success:
555-
return True
556-
557551
# TODO: we could also try servers which were previously in the room, but
558552
# are no longer.
559-
560-
return False
553+
return await try_backfill(likely_domains)
561554

562555
async def send_invite(self, target_host: str, event: EventBase) -> EventBase:
563556
"""Sends the invite to the remote server for signing.

synapse/handlers/pagination.py

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -577,27 +577,31 @@ async def get_messages(
577577
or missing_too_many_events
578578
or not_enough_events_to_fill_response
579579
):
580-
did_backfill = await self.hs.get_federation_handler().maybe_backfill(
580+
# Historical Note: There used to be a check here for if backfill was
581+
# successful or not
582+
await self.hs.get_federation_handler().maybe_backfill(
581583
room_id,
582584
curr_topo,
583585
limit=pagin_config.limit,
584586
)
585587

586-
# If we did backfill something, refetch the events from the database to
587-
# catch anything new that might have been added since we last fetched.
588-
if did_backfill:
589-
(
590-
events,
591-
next_key,
592-
_,
593-
) = await self.store.paginate_room_events_by_topological_ordering(
594-
room_id=room_id,
595-
from_key=from_token.room_key,
596-
to_key=to_room_key,
597-
direction=pagin_config.direction,
598-
limit=pagin_config.limit,
599-
event_filter=event_filter,
600-
)
588+
# Regardless if we backfilled or not, another worker or even a
589+
# simultaneous request may have backfilled for us while we were held
590+
# behind the linearizer. This should not have too much additional
591+
# database load as it will only be triggered if a backfill *might* have
592+
# been needed
593+
(
594+
events,
595+
next_key,
596+
_,
597+
) = await self.store.paginate_room_events_by_topological_ordering(
598+
room_id=room_id,
599+
from_key=from_token.room_key,
600+
to_key=to_room_key,
601+
direction=pagin_config.direction,
602+
limit=pagin_config.limit,
603+
event_filter=event_filter,
604+
)
601605
else:
602606
# Otherwise, we can backfill in the background for eventual
603607
# consistency's sake but we don't need to block the client waiting

0 commit comments

Comments
 (0)