Batch up notifications after event persistence (#14033)
parent
51436c8dd5
commit
7b7478e8b6
|
@ -0,0 +1 @@
|
||||||
|
Don't repeatedly wake up the same users for batched events.
|
|
@ -2240,8 +2240,8 @@ class FederationEventHandler:
|
||||||
event_pos = PersistedEventPosition(
|
event_pos = PersistedEventPosition(
|
||||||
self._instance_name, event.internal_metadata.stream_ordering
|
self._instance_name, event.internal_metadata.stream_ordering
|
||||||
)
|
)
|
||||||
await self._notifier.on_new_room_event(
|
await self._notifier.on_new_room_events(
|
||||||
event, event_pos, max_stream_token, extra_users=extra_users
|
[(event, event_pos)], max_stream_token, extra_users=extra_users
|
||||||
)
|
)
|
||||||
|
|
||||||
if event.type == EventTypes.Member and event.membership == Membership.JOIN:
|
if event.type == EventTypes.Member and event.membership == Membership.JOIN:
|
||||||
|
|
|
@ -1872,6 +1872,7 @@ class EventCreationHandler:
|
||||||
events_and_context, backfilled=backfilled
|
events_and_context, backfilled=backfilled
|
||||||
)
|
)
|
||||||
|
|
||||||
|
events_and_pos = []
|
||||||
for event in persisted_events:
|
for event in persisted_events:
|
||||||
if self._ephemeral_events_enabled:
|
if self._ephemeral_events_enabled:
|
||||||
# If there's an expiry timestamp on the event, schedule its expiry.
|
# If there's an expiry timestamp on the event, schedule its expiry.
|
||||||
|
@ -1880,25 +1881,23 @@ class EventCreationHandler:
|
||||||
stream_ordering = event.internal_metadata.stream_ordering
|
stream_ordering = event.internal_metadata.stream_ordering
|
||||||
assert stream_ordering is not None
|
assert stream_ordering is not None
|
||||||
pos = PersistedEventPosition(self._instance_name, stream_ordering)
|
pos = PersistedEventPosition(self._instance_name, stream_ordering)
|
||||||
|
events_and_pos.append((event, pos))
|
||||||
async def _notify() -> None:
|
|
||||||
try:
|
|
||||||
await self.notifier.on_new_room_event(
|
|
||||||
event, pos, max_stream_token, extra_users=extra_users
|
|
||||||
)
|
|
||||||
except Exception:
|
|
||||||
logger.exception(
|
|
||||||
"Error notifying about new room event %s",
|
|
||||||
event.event_id,
|
|
||||||
)
|
|
||||||
|
|
||||||
run_in_background(_notify)
|
|
||||||
|
|
||||||
if event.type == EventTypes.Message:
|
if event.type == EventTypes.Message:
|
||||||
# We don't want to block sending messages on any presence code. This
|
# We don't want to block sending messages on any presence code. This
|
||||||
# matters as sometimes presence code can take a while.
|
# matters as sometimes presence code can take a while.
|
||||||
run_in_background(self._bump_active_time, requester.user)
|
run_in_background(self._bump_active_time, requester.user)
|
||||||
|
|
||||||
|
async def _notify() -> None:
|
||||||
|
try:
|
||||||
|
await self.notifier.on_new_room_events(
|
||||||
|
events_and_pos, max_stream_token, extra_users=extra_users
|
||||||
|
)
|
||||||
|
except Exception:
|
||||||
|
logger.exception("Error notifying about new room events")
|
||||||
|
|
||||||
|
run_in_background(_notify)
|
||||||
|
|
||||||
return persisted_events[-1]
|
return persisted_events[-1]
|
||||||
|
|
||||||
async def _maybe_kick_guest_users(
|
async def _maybe_kick_guest_users(
|
||||||
|
|
|
@ -294,35 +294,31 @@ class Notifier:
|
||||||
"""
|
"""
|
||||||
self._new_join_in_room_callbacks.append(cb)
|
self._new_join_in_room_callbacks.append(cb)
|
||||||
|
|
||||||
async def on_new_room_event(
|
async def on_new_room_events(
|
||||||
self,
|
self,
|
||||||
event: EventBase,
|
events_and_pos: List[Tuple[EventBase, PersistedEventPosition]],
|
||||||
event_pos: PersistedEventPosition,
|
|
||||||
max_room_stream_token: RoomStreamToken,
|
max_room_stream_token: RoomStreamToken,
|
||||||
extra_users: Optional[Collection[UserID]] = None,
|
extra_users: Optional[Collection[UserID]] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Unwraps event and calls `on_new_room_event_args`."""
|
"""Creates a _PendingRoomEventEntry for each of the listed events and calls
|
||||||
await self.on_new_room_event_args(
|
notify_new_room_events with the results."""
|
||||||
event_pos=event_pos,
|
event_entries = []
|
||||||
room_id=event.room_id,
|
for event, pos in events_and_pos:
|
||||||
event_id=event.event_id,
|
entry = self.create_pending_room_event_entry(
|
||||||
event_type=event.type,
|
pos,
|
||||||
state_key=event.get("state_key"),
|
extra_users,
|
||||||
membership=event.content.get("membership"),
|
event.room_id,
|
||||||
max_room_stream_token=max_room_stream_token,
|
event.type,
|
||||||
extra_users=extra_users or [],
|
event.get("state_key"),
|
||||||
)
|
event.content.get("membership"),
|
||||||
|
)
|
||||||
|
event_entries.append((entry, event.event_id))
|
||||||
|
await self.notify_new_room_events(event_entries, max_room_stream_token)
|
||||||
|
|
||||||
async def on_new_room_event_args(
|
async def notify_new_room_events(
|
||||||
self,
|
self,
|
||||||
room_id: str,
|
event_entries: List[Tuple[_PendingRoomEventEntry, str]],
|
||||||
event_id: str,
|
|
||||||
event_type: str,
|
|
||||||
state_key: Optional[str],
|
|
||||||
membership: Optional[str],
|
|
||||||
event_pos: PersistedEventPosition,
|
|
||||||
max_room_stream_token: RoomStreamToken,
|
max_room_stream_token: RoomStreamToken,
|
||||||
extra_users: Optional[Collection[UserID]] = None,
|
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Used by handlers to inform the notifier something has happened
|
"""Used by handlers to inform the notifier something has happened
|
||||||
in the room, room event wise.
|
in the room, room event wise.
|
||||||
|
@ -338,22 +334,33 @@ class Notifier:
|
||||||
until all previous events have been persisted before notifying
|
until all previous events have been persisted before notifying
|
||||||
the client streams.
|
the client streams.
|
||||||
"""
|
"""
|
||||||
self.pending_new_room_events.append(
|
for event_entry, event_id in event_entries:
|
||||||
_PendingRoomEventEntry(
|
self.pending_new_room_events.append(event_entry)
|
||||||
event_pos=event_pos,
|
await self._third_party_rules.on_new_event(event_id)
|
||||||
extra_users=extra_users or [],
|
|
||||||
room_id=room_id,
|
|
||||||
type=event_type,
|
|
||||||
state_key=state_key,
|
|
||||||
membership=membership,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
self._notify_pending_new_room_events(max_room_stream_token)
|
self._notify_pending_new_room_events(max_room_stream_token)
|
||||||
|
|
||||||
await self._third_party_rules.on_new_event(event_id)
|
|
||||||
|
|
||||||
self.notify_replication()
|
self.notify_replication()
|
||||||
|
|
||||||
|
def create_pending_room_event_entry(
|
||||||
|
self,
|
||||||
|
event_pos: PersistedEventPosition,
|
||||||
|
extra_users: Optional[Collection[UserID]],
|
||||||
|
room_id: str,
|
||||||
|
event_type: str,
|
||||||
|
state_key: Optional[str],
|
||||||
|
membership: Optional[str],
|
||||||
|
) -> _PendingRoomEventEntry:
|
||||||
|
"""Creates and returns a _PendingRoomEventEntry"""
|
||||||
|
return _PendingRoomEventEntry(
|
||||||
|
event_pos=event_pos,
|
||||||
|
extra_users=extra_users or [],
|
||||||
|
room_id=room_id,
|
||||||
|
type=event_type,
|
||||||
|
state_key=state_key,
|
||||||
|
membership=membership,
|
||||||
|
)
|
||||||
|
|
||||||
def _notify_pending_new_room_events(
|
def _notify_pending_new_room_events(
|
||||||
self, max_room_stream_token: RoomStreamToken
|
self, max_room_stream_token: RoomStreamToken
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|
|
@ -210,15 +210,16 @@ class ReplicationDataHandler:
|
||||||
|
|
||||||
max_token = self.store.get_room_max_token()
|
max_token = self.store.get_room_max_token()
|
||||||
event_pos = PersistedEventPosition(instance_name, token)
|
event_pos = PersistedEventPosition(instance_name, token)
|
||||||
await self.notifier.on_new_room_event_args(
|
event_entry = self.notifier.create_pending_room_event_entry(
|
||||||
event_pos=event_pos,
|
event_pos,
|
||||||
max_room_stream_token=max_token,
|
extra_users,
|
||||||
extra_users=extra_users,
|
row.data.room_id,
|
||||||
room_id=row.data.room_id,
|
row.data.type,
|
||||||
event_id=row.data.event_id,
|
row.data.state_key,
|
||||||
event_type=row.data.type,
|
row.data.membership,
|
||||||
state_key=row.data.state_key,
|
)
|
||||||
membership=row.data.membership,
|
await self.notifier.notify_new_room_events(
|
||||||
|
[(event_entry, row.data.event_id)], max_token
|
||||||
)
|
)
|
||||||
|
|
||||||
# If this event is a join, make a note of it so we have an accurate
|
# If this event is a join, make a note of it so we have an accurate
|
||||||
|
|
Loading…
Reference in New Issue