diff options
Diffstat (limited to 'synapse/storage/__init__.py')
-rw-r--r-- | synapse/storage/__init__.py | 36 |
1 files changed, 33 insertions, 3 deletions
diff --git a/synapse/storage/__init__.py b/synapse/storage/__init__.py index 231ec8169f..87db382fbb 100644 --- a/synapse/storage/__init__.py +++ b/synapse/storage/__init__.py @@ -13,7 +13,11 @@ # See the License for the specific language governing permissions and # limitations under the License. -from .appservice import ApplicationServiceStore +from twisted.internet import defer +from .appservice import ( + ApplicationServiceStore, ApplicationServiceTransactionStore +) +from ._base import Cache from .directory import DirectoryStore from .events import EventsStore from .presence import PresenceStore @@ -51,6 +55,11 @@ SCHEMA_VERSION = 15 dir_path = os.path.abspath(os.path.dirname(__file__)) +# Number of msec of granularity to store the user IP 'last seen' time. Smaller +# times give more inserts into the database even for readonly API hits +# 120 seconds == 2 minutes +LAST_SEEN_GRANULARITY = 120*1000 + class DataStore(RoomMemberStore, RoomStore, RegistrationStore, StreamStore, ProfileStore, @@ -63,6 +72,7 @@ class DataStore(RoomMemberStore, RoomStore, FilteringStore, PusherStore, PushRuleStore, + ApplicationServiceTransactionStore, EventsStore, ): @@ -73,8 +83,28 @@ class DataStore(RoomMemberStore, RoomStore, self.min_token_deferred = self._get_min_token() self.min_token = None + self.client_ip_last_seen = Cache( + name="client_ip_last_seen", + keylen=4, + ) + + @defer.inlineCallbacks def insert_client_ip(self, user, access_token, device_id, ip, user_agent): - return self._simple_upsert( + now = int(self._clock.time_msec()) + key = (user.to_string(), access_token, device_id, ip) + + try: + last_seen = self.client_ip_last_seen.get(*key) + except KeyError: + last_seen = None + + # Rate-limited inserts + if last_seen is not None and (now - last_seen) < LAST_SEEN_GRANULARITY: + defer.returnValue(None) + + self.client_ip_last_seen.prefill(*key + (now,)) + + yield self._simple_upsert( "user_ips", keyvalues={ "user": user.to_string(), @@ -84,7 +114,7 @@ class DataStore(RoomMemberStore, RoomStore, }, values={ "device_id": device_id, - "last_seen": int(self._clock.time_msec()), + "last_seen": now, }, desc="insert_client_ip", ) |