Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.

Commit f871222

Browse files
authored
Move update_client_ip background job from the main process to the background worker. (#12251)
1 parent 319a805 commit f871222

File tree

10 files changed

+160
-153
lines changed

10 files changed

+160
-153
lines changed

changelog.d/12251.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Offload the `update_client_ip` background job from the main process to the background worker, when using Redis-based replication.

synapse/app/admin_cmd.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
from synapse.replication.slave.storage._base import BaseSlavedStore
3434
from synapse.replication.slave.storage.account_data import SlavedAccountDataStore
3535
from synapse.replication.slave.storage.appservice import SlavedApplicationServiceStore
36-
from synapse.replication.slave.storage.client_ips import SlavedClientIpStore
3736
from synapse.replication.slave.storage.deviceinbox import SlavedDeviceInboxStore
3837
from synapse.replication.slave.storage.devices import SlavedDeviceStore
3938
from synapse.replication.slave.storage.events import SlavedEventStore
@@ -61,7 +60,6 @@ class AdminCmdSlavedStore(
6160
SlavedDeviceStore,
6261
SlavedPushRuleStore,
6362
SlavedEventStore,
64-
SlavedClientIpStore,
6563
BaseSlavedStore,
6664
RoomWorkerStore,
6765
):

synapse/app/generic_worker.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@
5353
from synapse.replication.slave.storage._base import BaseSlavedStore
5454
from synapse.replication.slave.storage.account_data import SlavedAccountDataStore
5555
from synapse.replication.slave.storage.appservice import SlavedApplicationServiceStore
56-
from synapse.replication.slave.storage.client_ips import SlavedClientIpStore
5756
from synapse.replication.slave.storage.deviceinbox import SlavedDeviceInboxStore
5857
from synapse.replication.slave.storage.devices import SlavedDeviceStore
5958
from synapse.replication.slave.storage.directory import DirectoryStore
@@ -247,7 +246,6 @@ class GenericWorkerSlavedStore(
247246
SlavedApplicationServiceStore,
248247
SlavedRegistrationStore,
249248
SlavedProfileStore,
250-
SlavedClientIpStore,
251249
SlavedFilteringStore,
252250
MonthlyActiveUsersWorkerStore,
253251
MediaRepositoryStore,

synapse/replication/slave/storage/client_ips.py

Lines changed: 0 additions & 59 deletions
This file was deleted.

synapse/replication/tcp/commands.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ def __init__(
356356
access_token: str,
357357
ip: str,
358358
user_agent: str,
359-
device_id: str,
359+
device_id: Optional[str],
360360
last_seen: int,
361361
):
362362
self.user_id = user_id
@@ -389,6 +389,12 @@ def to_line(self) -> str:
389389
)
390390
)
391391

392+
def __repr__(self) -> str:
393+
return (
394+
f"UserIpCommand({self.user_id!r}, .., {self.ip!r}, "
395+
f"{self.user_agent!r}, {self.device_id!r}, {self.last_seen})"
396+
)
397+
392398

393399
class RemoteServerUpCommand(_SimpleCommand):
394400
"""Sent when a worker has detected that a remote server is no longer

synapse/replication/tcp/handler.py

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,14 @@ def __init__(self, hs: "HomeServer"):
235235
if self._is_master:
236236
self._server_notices_sender = hs.get_server_notices_sender()
237237

238+
if hs.config.redis.redis_enabled:
239+
# If we're using Redis, it's the background worker that should
240+
# receive USER_IP commands and store the relevant client IPs.
241+
self._should_insert_client_ips = hs.config.worker.run_background_tasks
242+
else:
243+
# If we're NOT using Redis, this must be handled by the master
244+
self._should_insert_client_ips = hs.get_instance_name() == "master"
245+
238246
def _add_command_to_stream_queue(
239247
self, conn: IReplicationConnection, cmd: Union[RdataCommand, PositionCommand]
240248
) -> None:
@@ -401,23 +409,37 @@ def on_USER_IP(
401409
) -> Optional[Awaitable[None]]:
402410
user_ip_cache_counter.inc()
403411

404-
if self._is_master:
412+
if self._is_master or self._should_insert_client_ips:
413+
# We make a point of only returning an awaitable if there's actually
414+
# something to do; on_USER_IP is not an async function, but
415+
# _handle_user_ip is.
416+
# If on_USER_IP returns an awaitable, it gets scheduled as a
417+
# background process (see `BaseReplicationStreamProtocol.handle_command`).
405418
return self._handle_user_ip(cmd)
406419
else:
420+
# Returning None when this process definitely has nothing to do
421+
# reduces the overhead of handling the USER_IP command, which is
422+
# currently broadcast to all workers regardless of utility.
407423
return None
408424

409425
async def _handle_user_ip(self, cmd: UserIpCommand) -> None:
410-
await self._store.insert_client_ip(
411-
cmd.user_id,
412-
cmd.access_token,
413-
cmd.ip,
414-
cmd.user_agent,
415-
cmd.device_id,
416-
cmd.last_seen,
417-
)
418-
419-
assert self._server_notices_sender is not None
420-
await self._server_notices_sender.on_user_ip(cmd.user_id)
426+
"""
427+
Handles a User IP, branching depending on whether we are the main process
428+
and/or the background worker.
429+
"""
430+
if self._is_master:
431+
assert self._server_notices_sender is not None
432+
await self._server_notices_sender.on_user_ip(cmd.user_id)
433+
434+
if self._should_insert_client_ips:
435+
await self._store.insert_client_ip(
436+
cmd.user_id,
437+
cmd.access_token,
438+
cmd.ip,
439+
cmd.user_agent,
440+
cmd.device_id,
441+
cmd.last_seen,
442+
)
421443

422444
def on_RDATA(self, conn: IReplicationConnection, cmd: RdataCommand) -> None:
423445
if cmd.instance_name == self._instance_name:
@@ -698,7 +720,7 @@ def send_user_ip(
698720
access_token: str,
699721
ip: str,
700722
user_agent: str,
701-
device_id: str,
723+
device_id: Optional[str],
702724
last_seen: int,
703725
) -> None:
704726
"""Tell the master that the user made a request."""

synapse/storage/databases/main/__init__.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
from .appservice import ApplicationServiceStore, ApplicationServiceTransactionStore
3434
from .cache import CacheInvalidationWorkerStore
3535
from .censor_events import CensorEventsStore
36-
from .client_ips import ClientIpStore
36+
from .client_ips import ClientIpWorkerStore
3737
from .deviceinbox import DeviceInboxStore
3838
from .devices import DeviceStore
3939
from .directory import DirectoryStore
@@ -49,7 +49,7 @@
4949
from .lock import LockStore
5050
from .media_repository import MediaRepositoryStore
5151
from .metrics import ServerMetricsStore
52-
from .monthly_active_users import MonthlyActiveUsersStore
52+
from .monthly_active_users import MonthlyActiveUsersWorkerStore
5353
from .openid import OpenIdStore
5454
from .presence import PresenceStore
5555
from .profile import ProfileStore
@@ -112,13 +112,13 @@ class DataStore(
112112
AccountDataStore,
113113
EventPushActionsStore,
114114
OpenIdStore,
115-
ClientIpStore,
115+
ClientIpWorkerStore,
116116
DeviceStore,
117117
DeviceInboxStore,
118118
UserDirectoryStore,
119119
GroupServerStore,
120120
UserErasureStore,
121-
MonthlyActiveUsersStore,
121+
MonthlyActiveUsersWorkerStore,
122122
StatsStore,
123123
RelationsStore,
124124
CensorEventsStore,

0 commit comments

Comments
 (0)