Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
When retention is enabled in a synapse server, sometimes events get p…
…urged from the database which still are reference as last seen (m.fully_read) in the events table. When the client tries to update its last seen message, the server code fails and returns a SynapseError: 404 - Could not find event. This results in rooms showing unread messages when they shouldn't and in my case, after changeing retentions values, even flickering unread notifications while typing new messages, making notifications useless and annoying. In synapse/handlers/read_marker.py the code tries to compare the old Event-ID stored in the database (m.fully_read) with the last read Event-ID supplied by the client. It tries to only update the m.fully_read only if the new Event-ID is newer than the old one. For this is_event_after() from synapse/storage/databases/main/events_worker.py is called, which then calls get_event_ordering() with the Event-ID of the new and old event. It should return a tuple of topological_ordering and stream_ordering of both events for comparison. When calling get_event_ordering() with the old Event-ID this must fail, because the Event-ID got purged from the database. The code does not account for that, it has allow_none=True set so simple_select_one() should return None and not fail, but that doesn't seem to work. I didn't dug deeper in to simple_select_one() but changed the following raise SynapseError in synapse/storage/databases/main/events_worker.py, which produces the SynapseError: 404 - Could not find event, and instead inserted a log message and returned the tuple (0, 0) so it is always lower than the Event-ID of the new event. Thus allowing the last read update code to run and set the new Event-ID in the database. This fixed this issue for me.
- Loading branch information