Stop DBOS listener thread on destroy

Task 13385 · Done · Coder · created · updated

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.

Pull request

Artifacts

Activity

  • Created
  • Run
  • Runner started
  • Runner ended (done)