-
Type:
Bug
-
Resolution: Duplicate
-
Priority:
Major - P3
-
None
-
Affects Version/s: None
-
Component/s: Monitoring
-
None
Detailed steps to reproduce the problem?
I found a race condition during the thread sanitizer investigation in PYTHON-6048. It can be reproduced by instrumenting the C extensions with -fsanitize=thread. Closing a client reports a data race between close() tearing down monitor sockets and a monitor thread still inside recv() on the same connection.
The tradeoff for fixing the race for synchronous client: close() blocks for up to ~1 s (typical ≤ 0.5 s) instead of returning instantly at 0 ms.
Overall current state:
- Sync clients: close() signals the monitor threads (heartbeat, RTT, and SRV polling for mongodb+srv:// clients) to stop but never joins them. The threads keep running after close() returns; that is the race the sanitizer caught.
- Async clients: close() joins monitor tasks, but with no timeout, so a monitor that never stops hangs close() forever.
- In both cases, joining can also happen while the topology lock is held, blocking unrelated server selection.
Desired state:
- close() waits for all of its monitor threads to stop before returning.
- Monitors are joined after the topology lock is released, within a single ~1 s cap, regardless of monitor count, so shutdown stays bounded no matter how many monitors the client has.
- Closing a mongodb+srv:// client costs no more than closing any other client: the SRV polling thread is covered by the same single deadline, with no SRV-specific fixed delay.
- Subinterpreter shutdown also joins monitors against a single deadline, not ~1 s per monitor.
Related tickets:
- PYTHON-2338 (unclosed _RttMonitor sockets when the executor stops before check-in)
PYTHON-5053(unbounded close joins)PYTHON-5418makes monitor threads non-daemon in subinterpreters and joins them at teardown ~1 s per executor, so the single shared deadline should also cover subinterpreter shutdown.
The exact Python version used, with patch level:
3.14.2 free-threaded (CPython 3.14.2t); the behavior reproduces on any CPython version.
The exact version of PyMongo used, with patch level:
4.19.0.dev0 (PYTHON-6048 branch); has_c() = True. The race window dates back to PYTHON-2123 (2020).
Describe how MongoDB is set up. Local vs Hosted, version, topology, load balanced, etc.
Local mongod 8.0, standalone and replica set topologies; streaming server monitoring (serverMonitoringMode=stream).
The operating system and version (e.g. Windows 7, OSX 10.8, ...)
Linux (Ubuntu 22.04/26.04, aarch64).
Web framework or asynchronous network library used, if any, with version (e.g. Django 1.7, mod_wsgi 4.3.0, gevent 1.0.1, Tornado 4.0.2, ...)
None.
Security Vulnerabilities
None identified - this is a correctness/latency issue, not a security vulnerability.
- duplicates
-
PYTHON-1634 Provide a way to join background threads when closing a MongoClient
-
- Ready for Work
-