Handle multiple rows device inbox (#17362)

Fix bug where we don't get new to-device from remote if they resent a
message we've already persisted and have recorded in the DB twice.

`device_federation_inbox` table doesn't have a unique index, and so we
can race and store an entry in there twice. If we do so then
`simple_select_one_txn` will throw an error due to the query returning
more than one row. We should add an unique index, but it doesn't really
matter so lets just handle the case of multiple rows correctly for now.
This commit is contained in:
Erik Johnston 2024-06-27 11:04:31 +01:00 committed by GitHub
parent 7c169f4d2c
commit cc5e5893fe
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 3 additions and 3 deletions

1
changelog.d/17362.bugfix Normal file
View File

@ -0,0 +1 @@
Fix rare race which causes no new to-device messages to be received from remote server.

View File

@ -825,14 +825,13 @@ class DeviceInboxWorkerStore(SQLBaseStore):
# Check if we've already inserted a matching message_id for that # Check if we've already inserted a matching message_id for that
# origin. This can happen if the origin doesn't receive our # origin. This can happen if the origin doesn't receive our
# acknowledgement from the first time we received the message. # acknowledgement from the first time we received the message.
already_inserted = self.db_pool.simple_select_one_txn( already_inserted = self.db_pool.simple_select_list_txn(
txn, txn,
table="device_federation_inbox", table="device_federation_inbox",
keyvalues={"origin": origin, "message_id": message_id}, keyvalues={"origin": origin, "message_id": message_id},
retcols=("message_id",), retcols=("message_id",),
allow_none=True,
) )
if already_inserted is not None: if already_inserted:
return return
# Add an entry for this message_id so that we know we've processed # Add an entry for this message_id so that we know we've processed