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

Commit

Permalink
Create a ListenerConfig object (#7681)
Browse files Browse the repository at this point in the history
This ended up being a bit more invasive than I'd hoped for (not helped by
generic_worker duplicating some of the code from homeserver), but hopefully
it's an improvement.

The idea is that, rather than storing unstructured `dict`s in the config for
the listener configurations, we instead parse it into a structured
`ListenerConfig` object.
  • Loading branch information
richvdh authored Jun 16, 2020
1 parent 7896065 commit 0361932
Show file tree
Hide file tree
Showing 13 changed files with 248 additions and 167 deletions.
1 change: 1 addition & 0 deletions changelog.d/7681.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Refactor handling of `listeners` configuration settings.
8 changes: 5 additions & 3 deletions synapse/app/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import socket
import sys
import traceback
from typing import Iterable

from daemonize import Daemonize
from typing_extensions import NoReturn
Expand All @@ -29,6 +30,7 @@

import synapse
from synapse.app import check_bind_error
from synapse.config.server import ListenerConfig
from synapse.crypto import context_factory
from synapse.logging.context import PreserveLoggingContext
from synapse.util.async_helpers import Linearizer
Expand Down Expand Up @@ -234,7 +236,7 @@ def refresh_certificate(hs):
logger.info("Context factories updated.")


def start(hs, listeners=None):
def start(hs: "synapse.server.HomeServer", listeners: Iterable[ListenerConfig]):
"""
Start a Synapse server or worker.
Expand All @@ -245,8 +247,8 @@ def start(hs, listeners=None):
notify systemd.
Args:
hs (synapse.server.HomeServer)
listeners (list[dict]): Listener configuration ('listeners' in homeserver.yaml)
hs: homeserver instance
listeners: Listener configuration ('listeners' in homeserver.yaml)
"""
try:
# Set up the SIGHUP machinery.
Expand Down
36 changes: 21 additions & 15 deletions synapse/app/generic_worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
from synapse.config._base import ConfigError
from synapse.config.homeserver import HomeServerConfig
from synapse.config.logger import setup_logging
from synapse.config.server import ListenerConfig
from synapse.federation import send_queue
from synapse.federation.transport.server import TransportLayerServer
from synapse.handlers.presence import (
Expand Down Expand Up @@ -514,13 +515,18 @@ def _get_federation_out_pos(self, db_conn):
class GenericWorkerServer(HomeServer):
DATASTORE_CLASS = GenericWorkerSlavedStore

def _listen_http(self, listener_config):
port = listener_config["port"]
bind_addresses = listener_config["bind_addresses"]
site_tag = listener_config.get("tag", port)
def _listen_http(self, listener_config: ListenerConfig):
port = listener_config.port
bind_addresses = listener_config.bind_addresses

assert listener_config.http_options is not None

site_tag = listener_config.http_options.tag
if site_tag is None:
site_tag = port
resources = {}
for res in listener_config["resources"]:
for name in res["names"]:
for res in listener_config.http_options.resources:
for name in res.names:
if name == "metrics":
resources[METRICS_PREFIX] = MetricsResource(RegistryProxy)
elif name == "client":
Expand Down Expand Up @@ -590,7 +596,7 @@ def _listen_http(self, listener_config):
" repository is disabled. Ignoring."
)

if name == "openid" and "federation" not in res["names"]:
if name == "openid" and "federation" not in res.names:
# Only load the openid resource separately if federation resource
# is not specified since federation resource includes openid
# resource.
Expand Down Expand Up @@ -625,19 +631,19 @@ def _listen_http(self, listener_config):

logger.info("Synapse worker now listening on port %d", port)

def start_listening(self, listeners):
def start_listening(self, listeners: Iterable[ListenerConfig]):
for listener in listeners:
if listener["type"] == "http":
if listener.type == "http":
self._listen_http(listener)
elif listener["type"] == "manhole":
elif listener.type == "manhole":
_base.listen_tcp(
listener["bind_addresses"],
listener["port"],
listener.bind_addresses,
listener.port,
manhole(
username="matrix", password="rabbithole", globals={"hs": self}
),
)
elif listener["type"] == "metrics":
elif listener.type == "metrics":
if not self.get_config().enable_metrics:
logger.warning(
(
Expand All @@ -646,9 +652,9 @@ def start_listening(self, listeners):
)
)
else:
_base.listen_metrics(listener["bind_addresses"], listener["port"])
_base.listen_metrics(listener.bind_addresses, listener.port)
else:
logger.warning("Unrecognized listener type: %s", listener["type"])
logger.warning("Unsupported listener type: %s", listener.type)

self.get_tcp_replication().start_replication(self)

Expand Down
50 changes: 27 additions & 23 deletions synapse/app/homeserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import os
import resource
import sys
from typing import Iterable

from prometheus_client import Gauge

Expand All @@ -48,6 +49,7 @@
from synapse.app._base import listen_ssl, listen_tcp, quit_with_error
from synapse.config._base import ConfigError
from synapse.config.homeserver import HomeServerConfig
from synapse.config.server import ListenerConfig
from synapse.federation.transport.server import TransportLayerServer
from synapse.http.additional_resource import AdditionalResource
from synapse.http.server import (
Expand Down Expand Up @@ -87,24 +89,24 @@ def gz_wrap(r):
class SynapseHomeServer(HomeServer):
DATASTORE_CLASS = DataStore

def _listener_http(self, config, listener_config):
port = listener_config["port"]
bind_addresses = listener_config["bind_addresses"]
tls = listener_config.get("tls", False)
site_tag = listener_config.get("tag", port)
def _listener_http(self, config: HomeServerConfig, listener_config: ListenerConfig):
port = listener_config.port
bind_addresses = listener_config.bind_addresses
tls = listener_config.tls
site_tag = listener_config.http_options.tag
if site_tag is None:
site_tag = port

resources = {}
for res in listener_config["resources"]:
for name in res["names"]:
if name == "openid" and "federation" in res["names"]:
for res in listener_config.http_options.resources:
for name in res.names:
if name == "openid" and "federation" in res.names:
# Skip loading openid resource if federation is defined
# since federation resource will include openid
continue
resources.update(
self._configure_named_resource(name, res.get("compress", False))
)
resources.update(self._configure_named_resource(name, res.compress))

additional_resources = listener_config.get("additional_resources", {})
additional_resources = listener_config.http_options.additional_resources
logger.debug("Configuring additional resources: %r", additional_resources)
module_api = ModuleApi(self, self.get_auth_handler())
for path, resmodule in additional_resources.items():
Expand Down Expand Up @@ -276,7 +278,7 @@ def _configure_named_resource(self, name, compress=False):

return resources

def start_listening(self, listeners):
def start_listening(self, listeners: Iterable[ListenerConfig]):
config = self.get_config()

if config.redis_enabled:
Expand All @@ -286,25 +288,25 @@ def start_listening(self, listeners):
self.get_tcp_replication().start_replication(self)

for listener in listeners:
if listener["type"] == "http":
if listener.type == "http":
self._listening_services.extend(self._listener_http(config, listener))
elif listener["type"] == "manhole":
elif listener.type == "manhole":
listen_tcp(
listener["bind_addresses"],
listener["port"],
listener.bind_addresses,
listener.port,
manhole(
username="matrix", password="rabbithole", globals={"hs": self}
),
)
elif listener["type"] == "replication":
elif listener.type == "replication":
services = listen_tcp(
listener["bind_addresses"],
listener["port"],
listener.bind_addresses,
listener.port,
ReplicationStreamProtocolFactory(self),
)
for s in services:
reactor.addSystemEventTrigger("before", "shutdown", s.stopListening)
elif listener["type"] == "metrics":
elif listener.type == "metrics":
if not self.get_config().enable_metrics:
logger.warning(
(
Expand All @@ -313,9 +315,11 @@ def start_listening(self, listeners):
)
)
else:
_base.listen_metrics(listener["bind_addresses"], listener["port"])
_base.listen_metrics(listener.bind_addresses, listener.port)
else:
logger.warning("Unrecognized listener type: %s", listener["type"])
# this shouldn't happen, as the listener type should have been checked
# during parsing
logger.warning("Unrecognized listener type: %s", listener.type)


# Gauges to expose monthly active user control metrics
Expand Down
Loading

0 comments on commit 0361932

Please sign in to comment.