3030
3131from prometheus_client import Counter
3232
33+ from twisted .internet .protocol import ReconnectingClientFactory
34+
3335from synapse .metrics import LaterGauge
34- from synapse .replication .tcp .client import ReplicationClientFactory
36+ from synapse .replication .tcp .client import DirectTcpReplicationClientFactory
3537from synapse .replication .tcp .commands import (
3638 ClearUserSyncsCommand ,
3739 Command ,
@@ -92,7 +94,7 @@ def __init__(self, hs):
9294 self ._pending_batches = {} # type: Dict[str, List[Any]]
9395
9496 # The factory used to create connections.
95- self ._factory = None # type: Optional[ReplicationClientFactory ]
97+ self ._factory = None # type: Optional[ReconnectingClientFactory ]
9698
9799 # The currently connected connections.
98100 self ._connections = [] # type: List[AbstractConnection]
@@ -119,11 +121,45 @@ def start_replication(self, hs):
119121 """Helper method to start a replication connection to the remote server
120122 using TCP.
121123 """
122- client_name = hs .config .worker_name
123- self ._factory = ReplicationClientFactory (hs , client_name , self )
124- host = hs .config .worker_replication_host
125- port = hs .config .worker_replication_port
126- hs .get_reactor ().connectTCP (host , port , self ._factory )
124+ if hs .config .redis .redis_enabled :
125+ from synapse .replication .tcp .redis import (
126+ RedisDirectTcpReplicationClientFactory ,
127+ )
128+ import txredisapi
129+
130+ logger .info (
131+ "Connecting to redis (host=%r port=%r DBID=%r)" ,
132+ hs .config .redis_host ,
133+ hs .config .redis_port ,
134+ hs .config .redis_dbid ,
135+ )
136+
137+ # We need two connections to redis, one for the subscription stream and
138+ # one to send commands to (as you can't send further redis commands to a
139+ # connection after SUBSCRIBE is called).
140+
141+ # First create the connection for sending commands.
142+ outbound_redis_connection = txredisapi .lazyConnection (
143+ host = hs .config .redis_host ,
144+ port = hs .config .redis_port ,
145+ dbid = hs .config .redis_dbid ,
146+ password = hs .config .redis .redis_password ,
147+ reconnect = True ,
148+ )
149+
150+ # Now create the factory/connection for the subscription stream.
151+ self ._factory = RedisDirectTcpReplicationClientFactory (
152+ hs , outbound_redis_connection
153+ )
154+ hs .get_reactor ().connectTCP (
155+ hs .config .redis .redis_host , hs .config .redis .redis_port , self ._factory ,
156+ )
157+ else :
158+ client_name = hs .config .worker_name
159+ self ._factory = DirectTcpReplicationClientFactory (hs , client_name , self )
160+ host = hs .config .worker_replication_host
161+ port = hs .config .worker_replication_port
162+ hs .get_reactor ().connectTCP (host , port , self ._factory )
127163
128164 async def on_REPLICATE (self , cmd : ReplicateCommand ):
129165 # We only want to announce positions by the writer of the streams.
0 commit comments