Stop DBOS listener thread on destroy
DBOS 3.2.0's `DBOS.destroy` (`_destroy` → `_sys_db._cleanup_connections`) closes the LISTEN connection from the calling thread while the notification listener thread is still inside psycopg's `notifies()` on it. With psycopg_c on free-threaded CPython this frees the PGconn under the waiting thread, a use-after-free. Task 13358 fixed it for the shared live-engine fixture (`tests/nodevault_support.py::stop_notification_listener`). These sites still call a bare `DBOS.destroy()` with the same race:
- tests: `test_cron_retention.py`, `test_durable_enqueue_engine.py`, `test_durable_shutdown_engine.py`, `test_live_cast_engine.py`, `test_nodevault_dbos_scan.py`
- served shutdown: `app/durable/runtime.py` (`asyncio.to_thread(DBOS.destroy, ...)`), where it runs at process exit
Requirements:
- Route every test site through one shared helper.
- Decide whether the served shutdown needs the same stop, or whether the fix belongs upstream in dbos itself: `_cleanup_connections` should stop its own listener thread rather than close another thread's connection.
Out of scope: unrelated DBOS upgrades and test-content changes.
Done means: no bare `DBOS.destroy` remains on a launched engine in tests without the listener stop; the quick gate and the touched suites pass.
Outcome
The served shutdown and every test teardown now destroy the DBOS engine through one helper, durable_runtime.destroy_engine, which stops the listener on its own thread first. Quick gate and touched suites green (112 passed). PR #7897 queued to the merge lane. Deferred: the upstream dbos fix.
Artifacts
Activity
- Created
- Run
- Runner started
- Runner ended (done)