Matthew Hodgson
ac26cfac83
Let me give you a clear summary of where this project stands:
...
---
Summary: Synapse Twisted → asyncio Migration
What's been built (Phases 0-7) — 10 new files, ~3200 lines, 96 tests
Every Twisted component has an asyncio-native replacement ready:
┌──────────────────┬───────────────────────────────────────────────┬─────────────────────────────────────────────────────────┬───────────────────────────────────────────────┐
│ Component │ Twisted Original │ asyncio Replacement │ File │
├──────────────────┼───────────────────────────────────────────────┼─────────────────────────────────────────────────────────┼───────────────────────────────────────────────┤
│ LoggingContext │ threading.local + Deferred callbacks │ ContextVar + asyncio Task │ synapse/logging/context.py (native functions) │
├──────────────────┼───────────────────────────────────────────────┼─────────────────────────────────────────────────────────┼───────────────────────────────────────────────┤
│ Async primitives │ ObservableDeferred, Linearizer, ReadWriteLock │ ObservableFuture, NativeLinearizer, NativeReadWriteLock │ synapse/util/async_helpers.py │
├──────────────────┼───────────────────────────────────────────────┼─────────────────────────────────────────────────────────┼───────────────────────────────────────────────┤
│ Cache │ DeferredCache │ FutureCache │ synapse/util/caches/future_cache.py │
├──────────────────┼───────────────────────────────────────────────┼─────────────────────────────────────────────────────────┼───────────────────────────────────────────────┤
│ Clock │ Clock (Twisted reactor) │ NativeClock (asyncio) │ synapse/util/clock.py │
├──────────────────┼───────────────────────────────────────────────┼─────────────────────────────────────────────────────────┼───────────────────────────────────────────────┤
│ Database │ adbapi.ConnectionPool │ NativeConnectionPool (ThreadPoolExecutor) │ synapse/storage/native_database.py │
├──────────────────┼───────────────────────────────────────────────┼─────────────────────────────────────────────────────────┼───────────────────────────────────────────────┤
│ HTTP Client │ treq + Twisted Agent │ aiohttp.ClientSession │ synapse/http/native_client.py │
├──────────────────┼───────────────────────────────────────────────┼─────────────────────────────────────────────────────────┼───────────────────────────────────────────────┤
│ HTTP Server │ JsonResource + Twisted Site │ NativeJsonResource + aiohttp.web │ synapse/http/native_server.py │
├──────────────────┼───────────────────────────────────────────────┼─────────────────────────────────────────────────────────┼───────────────────────────────────────────────┤
│ Replication │ LineOnlyReceiver (Twisted Protocol) │ asyncio.StreamReader/Writer │ synapse/replication/tcp/native_protocol.py │
├──────────────────┼───────────────────────────────────────────────┼─────────────────────────────────────────────────────────┼───────────────────────────────────────────────┤
│ Event loop │ ISynapseReactor │ ISynapseEventLoop │ synapse/types/__init__.py │
├──────────────────┼───────────────────────────────────────────────┼─────────────────────────────────────────────────────────┼───────────────────────────────────────────────┤
│ Test helper │ — │ FakeAsyncioLoop │ tests/async_helpers.py │
└──────────────────┴───────────────────────────────────────────────┴─────────────────────────────────────────────────────────┴───────────────────────────────────────────────┘
What's been wired in safely — 224 files changed, 0 regressions
- MemoryReactor type hint → Any across 198 test files (cosmetic)
- synapse/http/server.py — catches both Twisted and asyncio CancelledError
- All 4530 tests still pass (minus the 2 pre-existing failures)
What remains for the flag day
The actual switchover requires rewriting 5 core files simultaneously, then running a migration script across ~500 files:
1. tests/unittest.py + tests/server.py — switch from twisted.trial.TestCase to unittest.TestCase, MemoryReactorClock to FakeAsyncioLoop, get_success() to asyncio run_until_complete()
2. synapse/logging/context.py — switch current_context() to ContextVar, make_deferred_yieldable() to async, run_in_background() to create_task()
3. synapse/util/async_helpers.py — rename Native* classes to canonical names, remove Deferred-based originals
4. Migration script — update all CancelledError, defer.*, Deferred imports across ~500 files
5. pyproject.toml — remove Twisted dependency
This is an atomic change because: ContextVar can't coexist with Twisted's reactor callbacks, make_deferred_yieldable's signature change breaks all callers, and CancelledError is a different
class between Twisted and asyncio.
2026-03-21 16:17:04 +00:00
Erik Johnston
4906771da1
Faster redis replication handling ( #19138 )
...
Spawning a background process comes with a bunch of overhead, so let's
try to reduce the number of background processes we need to spawn when
handling inbound fed.
Currently, we seem to be doing roughly one per command. Instead, lets
keep the background process alive for a bit waiting for a new command to
come in.
2025-11-05 13:42:04 +00:00