Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Commit

Permalink
Check the stream position before checking if the cache is empty. (#14639
Browse files Browse the repository at this point in the history
)

An empty cache does not mean the entity has no changed, if
it is earlier than the earliest known stream position return that
the entity *has* changed since the cache cannot accurately
answer that query.
  • Loading branch information
clokep authored Dec 8, 2022
1 parent f3ad68c commit da77720
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 7 deletions.
1 change: 1 addition & 0 deletions changelog.d/14639.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix a long-standing bug where the user directory and room/user stats might be out of sync.
9 changes: 5 additions & 4 deletions synapse/util/caches/stream_change_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,16 +213,17 @@ def has_any_entity_changed(self, stream_pos: int) -> bool:
"""
assert isinstance(stream_pos, int)

if not self._cache:
# If the cache is empty, nothing can have changed.
return False

# _cache is not valid at or before the earliest known stream position, so
# return that an entity has changed.
if stream_pos <= self._earliest_known_stream_pos:
self.metrics.inc_misses()
return True

# If the cache is empty, nothing can have changed.
if not self._cache:
self.metrics.inc_misses()
return False

self.metrics.inc_hits()
return stream_pos < self._cache.peekitem()[0]

Expand Down
7 changes: 4 additions & 3 deletions tests/util/test_stream_change_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,10 @@ def test_has_any_entity_changed(self) -> None:
"""
cache = StreamChangeCache("#test", 1)

# With no entities, it returns False for the past, present, and future.
self.assertFalse(cache.has_any_entity_changed(0))
self.assertFalse(cache.has_any_entity_changed(1))
# With no entities, it returns True for the past, present, and False for
# the future.
self.assertTrue(cache.has_any_entity_changed(0))
self.assertTrue(cache.has_any_entity_changed(1))
self.assertFalse(cache.has_any_entity_changed(2))

# We add an entity
Expand Down

0 comments on commit da77720

Please sign in to comment.