From 738ccf61c01df04e1aef521ea7d1ae2844784214 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Mon, 8 May 2017 15:32:18 +0100 Subject: [PATCH 1/4] Cache check to see if device exists --- synapse/storage/devices.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/synapse/storage/devices.py b/synapse/storage/devices.py index c8d5f5ba8b8c..fc87c92182ca 100644 --- a/synapse/storage/devices.py +++ b/synapse/storage/devices.py @@ -18,7 +18,7 @@ from twisted.internet import defer from synapse.api.errors import StoreError -from ._base import SQLBaseStore +from ._base import SQLBaseStore, Cache from synapse.util.caches.descriptors import cached, cachedList, cachedInlineCallbacks @@ -29,6 +29,12 @@ class DeviceStore(SQLBaseStore): def __init__(self, hs): super(DeviceStore, self).__init__(hs) + self.device_id_exists_cache = Cache( + name="device_id_exists", + keylen=2, + max_entries=10000, + ) + self._clock.looping_call( self._prune_old_outbound_device_pokes, 60 * 60 * 1000 ) @@ -54,6 +60,10 @@ def store_device(self, user_id, device_id, defer.Deferred: boolean whether the device was inserted or an existing device existed with that ID. """ + key = (user_id, device_id) + if self.device_id_exists_cache.get(key, None): + defer.returnValue(False) + try: inserted = yield self._simple_insert( "devices", @@ -65,6 +75,7 @@ def store_device(self, user_id, device_id, desc="store_device", or_ignore=True, ) + self.device_id_exists_cache.prefill(key, True) defer.returnValue(inserted) except Exception as e: logger.error("store_device with device_id=%s(%r) user_id=%s(%r)" From fc6d4974a60a0d47492f5c5c8dff45abbf9abe03 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Mon, 8 May 2017 15:33:57 +0100 Subject: [PATCH 2/4] Comment --- synapse/storage/devices.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/synapse/storage/devices.py b/synapse/storage/devices.py index fc87c92182ca..6727861eb5e9 100644 --- a/synapse/storage/devices.py +++ b/synapse/storage/devices.py @@ -29,6 +29,8 @@ class DeviceStore(SQLBaseStore): def __init__(self, hs): super(DeviceStore, self).__init__(hs) + # Map of (user_id, device_id) -> bool. If there is an entry that implies + # the device exists. self.device_id_exists_cache = Cache( name="device_id_exists", keylen=2, From 94e6ad71f5445e014f3c9f6c260ab664635c7b59 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Mon, 8 May 2017 15:55:59 +0100 Subject: [PATCH 3/4] Invalidate cache on device deletion --- synapse/storage/devices.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/synapse/storage/devices.py b/synapse/storage/devices.py index 6727861eb5e9..75c30abc28f3 100644 --- a/synapse/storage/devices.py +++ b/synapse/storage/devices.py @@ -115,12 +115,14 @@ def delete_device(self, user_id, device_id): Returns: defer.Deferred """ - return self._simple_delete_one( + self._simple_delete_one( table="devices", keyvalues={"user_id": user_id, "device_id": device_id}, desc="delete_device", ) + self.device_id_exists_cache.invalidate((user_id, device_id)) + def delete_devices(self, user_id, device_ids): """Deletes several devices. @@ -130,13 +132,15 @@ def delete_devices(self, user_id, device_ids): Returns: defer.Deferred """ - return self._simple_delete_many( + self._simple_delete_many( table="devices", column="device_id", iterable=device_ids, keyvalues={"user_id": user_id}, desc="delete_devices", ) + for device_id in device_ids: + self.device_id_exists_cache.invalidate((user_id, device_id)) def update_device(self, user_id, device_id, new_display_name=None): """Update a device. From 6a12998a83791137db0b7988646cfc4bff572427 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Mon, 8 May 2017 16:10:51 +0100 Subject: [PATCH 4/4] Add missing yields --- synapse/storage/devices.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/synapse/storage/devices.py b/synapse/storage/devices.py index 75c30abc28f3..d9936c88bb36 100644 --- a/synapse/storage/devices.py +++ b/synapse/storage/devices.py @@ -106,6 +106,7 @@ def get_device(self, user_id, device_id): desc="get_device", ) + @defer.inlineCallbacks def delete_device(self, user_id, device_id): """Delete a device. @@ -115,7 +116,7 @@ def delete_device(self, user_id, device_id): Returns: defer.Deferred """ - self._simple_delete_one( + yield self._simple_delete_one( table="devices", keyvalues={"user_id": user_id, "device_id": device_id}, desc="delete_device", @@ -123,6 +124,7 @@ def delete_device(self, user_id, device_id): self.device_id_exists_cache.invalidate((user_id, device_id)) + @defer.inlineCallbacks def delete_devices(self, user_id, device_ids): """Deletes several devices. @@ -132,7 +134,7 @@ def delete_devices(self, user_id, device_ids): Returns: defer.Deferred """ - self._simple_delete_many( + yield self._simple_delete_many( table="devices", column="device_id", iterable=device_ids,