From 88f2f756a4fb0976a0e6424790ecd4b3222810f5 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Tue, 24 Mar 2026 19:29:37 -0400 Subject: [PATCH] =?UTF-8?q?=20=20The=20fix=20was=20simple:=20=5Fget=5Floop?= =?UTF-8?q?()=20in=20NativeClock=20now=20falls=20back=20to=20asyncio.get?= =?UTF-8?q?=5Fevent=5Floop()=20when=20asyncio.get=5Frunning=5Floop()=20fai?= =?UTF-8?q?ls=20(which=20happens=20during=20startup=20before=20the=20event?= =?UTF-8?q?=20loop=20is=20running).=20This=20allows=20call=5Flater(),=20?= =?UTF-8?q?=20=20looping=5Fcall(),=20and=20other=20scheduling=20methods=20?= =?UTF-8?q?to=20work=20during=20the=20synchronous=20setup()=20phase=20?= =?UTF-8?q?=E2=80=94=20the=20tasks/timers=20are=20registered=20on=20the=20?= =?UTF-8?q?loop=20and=20execute=20once=20it=20starts=20running.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- synapse/util/clock.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/synapse/util/clock.py b/synapse/util/clock.py index 9933ed1d3a..5a20ba7bf4 100644 --- a/synapse/util/clock.py +++ b/synapse/util/clock.py @@ -174,7 +174,13 @@ class NativeClock: def _get_loop(self) -> asyncio.AbstractEventLoop: if self._loop is None: - self._loop = asyncio.get_running_loop() + try: + self._loop = asyncio.get_running_loop() + except RuntimeError: + # No running loop yet (e.g. during startup before the + # event loop is started). Fall back to get_event_loop() + # which returns the current thread's loop. + self._loop = asyncio.get_event_loop() return self._loop def shutdown(self) -> None: @@ -285,7 +291,7 @@ class NativeClock: await self.sleep(Duration(seconds=interval)) - loop = asyncio.get_running_loop() + loop = self._get_loop() task_obj = loop.create_task(_loop()) call = NativeLoopingCall(task_obj) self._looping_calls.add(call)