1 files changed, 28 insertions, 10 deletions
diff --git a/synapse/storage/databases/main/client_ips.py b/synapse/storage/databases/main/client_ips.py
index 4ea56331c7..4a57af1a0e 100644
--- a/synapse/storage/databases/main/client_ips.py
+++ b/synapse/storage/databases/main/client_ips.py
@@ -465,18 +465,15 @@ class ClientIpWorkerStore(ClientIpBackgroundUpdateStore, MonthlyActiveUsersWorke
#
# This works by finding the max last_seen that is less than the given
# time, but has no more than N rows before it, deleting all rows with
- # a lesser last_seen time. (We COALESCE so that the sub-SELECT always
- # returns exactly one row).
+ # a lesser last_seen time. (We use an `IN` clause to force postgres to
+ # use the index, otherwise it tends to do a seq scan).
sql = """
DELETE FROM user_ips
- WHERE last_seen <= (
- SELECT COALESCE(MAX(last_seen), -1)
- FROM (
- SELECT last_seen FROM user_ips
- WHERE last_seen <= ?
- ORDER BY last_seen ASC
- LIMIT 5000
- ) AS u
+ WHERE last_seen IN (
+ SELECT last_seen FROM user_ips
+ WHERE last_seen <= ?
+ ORDER BY last_seen ASC
+ LIMIT 5000
)
"""
@@ -589,6 +586,27 @@ class ClientIpWorkerStore(ClientIpBackgroundUpdateStore, MonthlyActiveUsersWorke
device_id: Optional[str],
now: Optional[int] = None,
) -> None:
+ """Record that `user_id` used `access_token` from this `ip` address.
+
+ This method does two things.
+
+ 1. It queues up a row to be upserted into the `client_ips` table. These happen
+ periodically; see _update_client_ips_batch.
+ 2. It immediately records this user as having taken action for the purposes of
+ MAU tracking.
+
+ Any DB writes take place on the background tasks worker, falling back to the
+ main process. If we're not that worker, this method emits a replication payload
+ to run this logic on that worker.
+
+ Two caveats to note:
+
+ - We only take action once per LAST_SEEN_GRANULARITY, to avoid spamming the
+ DB with writes.
+ - Requests using the sliding-sync proxy's user agent are excluded, as its
+ requests are not directly driven by end-users. This is a hack and we're not
+ very proud of it.
+ """
# The sync proxy continuously triggers /sync even if the user is not
# present so should be excluded from user_ips entries.
if user_agent == "sync-v3-proxy-":
|