Skip to content

Commit f51e1fe

Browse files
committed
Fix Synapse unable to shutdown after failing to bind ports during start
1 parent 72ca424 commit f51e1fe

3 files changed

Lines changed: 47 additions & 30 deletions

File tree

synapse/app/_base.py

Lines changed: 41 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -447,39 +447,50 @@ def listen_http(
447447
hs=hs,
448448
)
449449

450-
if isinstance(listener_config, TCPListenerConfig):
451-
if listener_config.is_tls():
452-
# refresh_certificate should have been called before this.
453-
assert context_factory is not None
454-
ports = listen_ssl(
455-
listener_config.bind_addresses,
456-
listener_config.port,
457-
site,
458-
context_factory,
459-
reactor=reactor,
450+
try:
451+
if isinstance(listener_config, TCPListenerConfig):
452+
if listener_config.is_tls():
453+
# refresh_certificate should have been called before this.
454+
assert context_factory is not None
455+
ports = listen_ssl(
456+
listener_config.bind_addresses,
457+
listener_config.port,
458+
site,
459+
context_factory,
460+
reactor=reactor,
461+
)
462+
logger.info(
463+
"Synapse now listening on TCP port %d (TLS)", listener_config.port
464+
)
465+
else:
466+
ports = listen_tcp(
467+
listener_config.bind_addresses,
468+
listener_config.port,
469+
site,
470+
reactor=reactor,
471+
)
472+
logger.info(
473+
"Synapse now listening on TCP port %d", listener_config.port
474+
)
475+
476+
else:
477+
ports = listen_unix(
478+
listener_config.path, listener_config.mode, site, reactor=reactor
460479
)
480+
# getHost() returns a UNIXAddress which contains an instance variable of 'name'
481+
# encoded as a byte string. Decode as utf-8 so pretty.
461482
logger.info(
462-
"Synapse now listening on TCP port %d (TLS)", listener_config.port
463-
)
464-
else:
465-
ports = listen_tcp(
466-
listener_config.bind_addresses,
467-
listener_config.port,
468-
site,
469-
reactor=reactor,
483+
"Synapse now listening on Unix Socket at: %s",
484+
ports[0].getHost().name.decode("utf-8"),
470485
)
471-
logger.info("Synapse now listening on TCP port %d", listener_config.port)
472-
473-
else:
474-
ports = listen_unix(
475-
listener_config.path, listener_config.mode, site, reactor=reactor
476-
)
477-
# getHost() returns a UNIXAddress which contains an instance variable of 'name'
478-
# encoded as a byte string. Decode as utf-8 so pretty.
479-
logger.info(
480-
"Synapse now listening on Unix Socket at: %s",
481-
ports[0].getHost().name.decode("utf-8"),
482-
)
486+
except Exception as exc:
487+
# The Twisted interface says that "Users should not call this function
488+
# themselves!" but this appears to be the correct way handle proper cleanup of
489+
# the site when things go wrong. In the normal case, a `Port` is created which
490+
# we can call `Port.stopListening()` on to do the same thing (but no `Port` is
491+
# created when an error occurs).
492+
site.doStop()
493+
raise Exception("asdf failed to listen") from exc
483494

484495
return ports
485496

synapse/http/site.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -815,6 +815,10 @@ def stopFactory(self) -> None:
815815
protocol.transport.loseConnection()
816816
self.connections.clear()
817817

818+
# Replace the resource tree with an empty resource to break circular references
819+
# to the resource tree which holds a bunch of homeserver references.
820+
self.resource = Resource()
821+
818822
def log(self, request: SynapseRequest) -> None: # type: ignore[override]
819823
pass
820824

synapse/server.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,8 @@ async def shutdown(self) -> None:
450450
# if gc.is_tracked(self):
451451
# logger.error("HomeServer object is tracked by garbage collection so cannot be fully cleaned up")
452452

453+
logger.info("asdf self._listening_services %s", self._listening_services)
454+
453455
for listener in self._listening_services:
454456
# During unit tests, an incomplete `twisted.pair.testing._FakePort` is used
455457
# for listeners so check listener type here to ensure shutdown procedure is

0 commit comments

Comments
 (0)