Skip to content

Commit b6171d5

Browse files
committed
perf(watchd): read the sequence number once per room, not per event
record_event called next_seq() for every incoming event, and next_seq reads the entire log plus its rotated generation. On a log of tens of thousands of records that is megabytes of parsing per message, and it grows with the log - a busy room would get slower the longer the daemon ran. The number is now read once per room and carried in memory. Safe because the daemon is the only writer: it holds the store lock for its whole run and nothing else appends to these logs. Found reviewing the implementation before merge, not by a test - the cost is invisible to a correctness test and only shows on a log with history. Signed-off-by: Sebastian Mendel <info@sebastianmendel.de>
1 parent 499dbba commit b6171d5

1 file changed

Lines changed: 18 additions & 1 deletion

File tree

skills/matrix-communication/scripts/matrix-watchd.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,18 +168,35 @@ def __init__(self, config: dict, credentials: dict):
168168
self.last_sync = None
169169
self.display_name = None
170170
self.stopping = asyncio.Event()
171+
self.next_seq_by_room = {}
171172

172173
# -- logging -----------------------------------------------------------
173174

174175
def record_event(self, room_id: str, event_dict: dict) -> None:
176+
"""Append one event to its room's log.
177+
178+
The sequence number is read from the log once per room and then carried
179+
in memory. Asking `next_seq` every time would re-read the whole log -
180+
and its rotated generation - for every incoming message, which on a log
181+
of tens of thousands of records means parsing megabytes per message in
182+
a busy room.
183+
184+
Safe to cache because the daemon is the only writer: it holds the store
185+
lock for its whole run, and nothing else appends to these logs.
186+
"""
175187
path = log_path(rooms_dir(), room_id)
188+
seq = self.next_seq_by_room.get(room_id)
189+
if seq is None:
190+
seq = next_seq(path)
191+
176192
record = build_record(
177-
seq=next_seq(path),
193+
seq=seq,
178194
event=event_dict,
179195
own_user_id=self.credentials["user_id"],
180196
own_display_name=self.display_name,
181197
)
182198
append_record(path, record)
199+
self.next_seq_by_room[room_id] = seq + 1
183200

184201
def announce(self, text: str) -> None:
185202
"""Put a daemon-level message into every watched log.

0 commit comments

Comments
 (0)