Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/18886.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Start background tasks after we fork the process (daemonize).
15 changes: 15 additions & 0 deletions synapse/app/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,21 @@ def run_sighup(*args: Any, **kwargs: Any) -> None:
hs.get_datastores().main.db_pool.start_profiling()
hs.get_pusherpool().start()

# Register background tasks required by this server. This must be done
# somewhat manually due to the background tasks not being registered
# unless handlers are instantiated.
#
# While we could "start" these before the reactor runs, nothing will happen
# until the reactor is running, so we may as well do it here in `start`.
#
# Additionally, this means we also start them after we daemonize and fork the
# process which means we can avoid any potential problems with cputime metrics getting
# confused about the per-thread resource usage appearing to go backwards because
# we're comparing the resource usage (`rusage`) from the original process to the
# forked process.
if hs.config.worker.run_background_tasks:
hs.start_background_tasks()

# Log when we start the shut down process.
hs.get_reactor().addSystemEventTrigger(
"before", "shutdown", logger.info, "Shutting down..."
Expand Down
8 changes: 1 addition & 7 deletions synapse/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -366,12 +366,6 @@ def setup(self) -> None:
self.datastores = Databases(self.DATASTORE_CLASS, self)
logger.info("Finished setting up.")

# Register background tasks required by this server. This must be done
# somewhat manually due to the background tasks not being registered
# unless handlers are instantiated.
if self.config.worker.run_background_tasks:
self.setup_background_tasks()
Comment on lines -369 to -373
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In terms of where we moved this code from and to:

Relevant starting point is here:

def main() -> None:
with LoggingContext("main"):
# check base requirements
check_requirements()
hs = setup(sys.argv[1:])
# redirect stdio to the logs, if configured.
if not hs.config.logging.no_redirect_stdio:
redirect_stdio_to_logs()
run(hs)

The main thing to see here is setup() vs run(). We fork the process in run() and then start the reactor after.

Previously, we started the background tasks in the setup() phase.

Now we start the background tasks in start which happens "once the reactor is running".


def __del__(self) -> None:
"""
Called when an the homeserver is garbage collected.
Expand Down Expand Up @@ -410,7 +404,7 @@ def start_listening(self) -> None: # noqa: B027 (no-op by design)
appropriate listeners.
"""

def setup_background_tasks(self) -> None:
def start_background_tasks(self) -> None:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a rename to align with it's new home in start(). I think either could fit but this might be more straightforward to understand.

"""
Some handlers have side effects on instantiation (like registering
background updates). This function causes them to be fetched, and
Expand Down
Loading