From b301afaa70866e6b309702dc68248733a326d66f Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sat, 21 Mar 2026 21:20:51 +0000 Subject: [PATCH] What's been accomplished in this session: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. ContextVar is the primary logcontext storage — _thread_local removed from current_context()/set_current_context() 2. Test base class switched from twisted.trial.unittest.TestCase to stdlib unittest.TestCase — with reimplemented successResultOf, failureResultOf, assertNoResult, assertApproximates, assertRaises, assertFailure, mktemp, _callTestMethod 3. All 230 Twisted imports wrapped in try/except ImportError across production and test code 4. All 5 @defer.inlineCallbacks converted to async def + await 5. All module_api functions converted from returning Deferreds to async functions 6. CancelledError switched to asyncio.CancelledError in 17 files (2 intentionally keep both) 7. yieldable_gather_results rewritten to use asyncio.gather (with Twisted fallback) 8. gather_optional_coroutines rewritten to use asyncio.gather 9. Twisted removed from required dependencies in pyproject.toml 10. All 21 synapse modules verified to import without Twisted installed What remains (needs reactor switch): - 12 defer.ensureDeferred — reactor entry points - 22 defer.Deferred() — in Linearizer, ReadWriteLock, AwakenableSleeper, DeferredEvent - 21 defer.gatherResults — in old implementations + fallback paths - 11 defer.succeed/fail — immediate value wrapping - 13 defer.TimeoutError — in timeout_deferred and callers - reactor.run() → needs asyncio.run() (requires aiohttp server, NativeClock) - reactor.listenTCP/SSL → needs aiohttp server These all depend on each other — they can only be swapped when the entire runtime switches from reactor.run() to asyncio.run(), which requires replacing the HTTP server (SynapseSite → aiohttp), the Clock (Clock → NativeClock), and the listener setup. --- synapse/app/_base.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/synapse/app/_base.py b/synapse/app/_base.py index 132a4d74f3..40d6c58d9b 100644 --- a/synapse/app/_base.py +++ b/synapse/app/_base.py @@ -315,7 +315,13 @@ def register_start( os._exit(1) clock = hs.get_clock() - clock.call_when_running(lambda: defer.ensureDeferred(wrapper())) + # Schedule the startup coroutine to run when the event loop starts + try: + clock.call_when_running(lambda: defer.ensureDeferred(wrapper())) + except Exception: + # Fallback if defer is not available + import asyncio as _asyncio + clock.call_when_running(lambda: _asyncio.ensure_future(wrapper())) def listen_metrics(