diff options
author | Richard van der Hoff <1389908+richvdh@users.noreply.github.com> | 2020-04-03 10:40:22 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-03 10:40:22 +0100 |
commit | daa1ac89a0be4dd3cc941da4caeb2ddcbd701eff (patch) | |
tree | 58ee94b0cfead33ff1aa6cb7420873db994a953c /synapse/storage/data_stores | |
parent | Merge branch 'master' into develop (diff) | |
download | synapse-daa1ac89a0be4dd3cc941da4caeb2ddcbd701eff.tar.xz |
Fix device list update stream ids going backward (#7158)
Occasionally we could get a federation device list update transaction which looked like: ``` [ {'edu_type': 'm.device_list_update', 'content': {'user_id': '@user:test', 'device_id': 'D2', 'prev_id': [], 'stream_id': 12, 'deleted': True}}, {'edu_type': 'm.device_list_update', 'content': {'user_id': '@user:test', 'device_id': 'D1', 'prev_id': [12], 'stream_id': 11, 'deleted': True}}, {'edu_type': 'm.device_list_update', 'content': {'user_id': '@user:test', 'device_id': 'D3', 'prev_id': [11], 'stream_id': 13, 'deleted': True}} ] ``` Having `stream_ids` which are lower than `prev_ids` looks odd. It might work (I'm not actually sure), but in any case it doesn't seem like a reasonable thing to expect other implementations to support.
Diffstat (limited to 'synapse/storage/data_stores')
-rw-r--r-- | synapse/storage/data_stores/main/devices.py | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/synapse/storage/data_stores/main/devices.py b/synapse/storage/data_stores/main/devices.py index 20995e1b78..dd3561e9b2 100644 --- a/synapse/storage/data_stores/main/devices.py +++ b/synapse/storage/data_stores/main/devices.py @@ -165,7 +165,6 @@ class DeviceWorkerStore(SQLBaseStore): # the max stream_id across each set of duplicate entries # # maps (user_id, device_id) -> (stream_id, opentracing_context) - # as long as their stream_id does not match that of the last row # # opentracing_context contains the opentracing metadata for the request # that created the poke @@ -270,7 +269,14 @@ class DeviceWorkerStore(SQLBaseStore): prev_id = yield self._get_last_device_update_for_remote_user( destination, user_id, from_stream_id ) - for device_id, device in iteritems(user_devices): + + # make sure we go through the devices in stream order + device_ids = sorted( + user_devices.keys(), key=lambda i: query_map[(user_id, i)][0], + ) + + for device_id in device_ids: + device = user_devices[device_id] stream_id, opentracing_context = query_map[(user_id, device_id)] result = { "user_id": user_id, |