Skip to content

Conversation

sleepyStick
Copy link
Contributor

@sleepyStick sleepyStick commented Oct 4, 2024

I created an AsyncPeriodicExecutor class because it differs enough from the regular PeriodicExecutor class -> this resulted in moving up periodic_executor.py up to the top level.

In the process of working on this ticket, I noticed some bugs in the tests (async tests using wait_until instead of async_wait_until) that are now appearing since background tasks are running in the event loop instead of on threads.

if _IS_SYNC:
_shutdown_resources()
else:
asyncio.run(_shutdown_resources())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This won't work because there is already an event loop running, we need something like https://github.com/minrk/asyncio-atexit

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, something was funky HAHA thanks for showing me a fix!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would i be allowed to import this and use the package? or should i just take the code that we need and put in on our own code base? thoughts?

Copy link
Member

@ShaneHarvey ShaneHarvey Oct 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this at all? What happens if we do nothing for async clients at exit?

Do our SDAM tasks prevent the loop from exiting?

We document that an AsyncMongoClient must always be closed() so I don't believe we need to do anything. If the app leaves the client open, that's a bug.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took it out of async and it seems to be fine so far.

@@ -28,6 +28,99 @@
_IS_SYNC = True


class SyncPeriodicExecutor:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should organize the code such that we don't sync this code since it will never be used.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As in move this file out of the async / sync folders right? If so, that makes sense to me :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep. We can have one file that has both.

return
global async_client_context
await async_teardown()
async_client_context = AsyncClientContext()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't work because the old client_context was already imported by other files so this change won't be reflected there. For example:

>>> import pymongo
>>> from pymongo import ASCENDING
>>> ASCENDING
1
>>> pymongo.ASCENDING = 2
>>> ASCENDING
1
>>> pymongo.ASCENDING
2

Instead we need to mutate the existing ClientContext

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahhh that makes sense, thanks!

@ShaneHarvey
Copy link
Member

ShaneHarvey commented Oct 10, 2024

One issue: A test emits an error from the _process_kill_cursors task (I'm not sure if this is expected or not):

 [2024/10/10 11:45:30.928] test/asynchronous/test_client.py::TestClient::test_max_idle_time_reaper_removes_stale PASSED [  4%]
 [2024/10/10 11:45:32.029] test/asynchronous/test_client.py::TestClient::test_max_idle_time_reaper_removes_stale_minPoolSize PASSED [  4%]
 [2024/10/10 11:45:33.444] test/asynchronous/test_client.py::TestClient::test_min_pool_size PASSED  [  4%]
 [2024/10/10 11:45:33.448] test/asynchronous/test_client.py::TestClient::test_multiple_uris PASSED  [  4%]
 [2024/10/10 11:45:33.519] test/asynchronous/test_client.py::TestClient::test_network_error_message PASSED [  4%]
 [2024/10/10 11:45:33.604] test/asynchronous/test_client.py::TestClient::test_operation_failure PASSED [  4%]
 [2024/10/10 11:45:33.703] + export PIP_PREFER_BINARY=1
 [2024/10/10 11:45:33.703] + PIP_PREFER_BINARY=1
 [2024/10/10 11:45:33.703] + set +x
 [2024/10/10 11:45:33.703] Traceback (most recent call last):
 [2024/10/10 11:45:33.703]   File "/data/mci/778c9688944da7ebf97a2e5c75defa03/src/pymongo/asynchronous/mongo_client.py", line 2056, in _process_kill_cursors
 [2024/10/10 11:45:33.703]     await self._kill_cursors(cursor_ids, address, topology, session=None)
 [2024/10/10 11:45:33.703]   File "/data/mci/778c9688944da7ebf97a2e5c75defa03/src/pymongo/asynchronous/mongo_client.py", line 2007, in _kill_cursors
 [2024/10/10 11:45:33.703]     async with self._checkout(server, session) as conn:
 [2024/10/10 11:45:33.703]   File "/opt/python/3.10/lib/python3.10/contextlib.py", line 199, in __aenter__
 [2024/10/10 11:45:33.703]     return await anext(self.gen)
 [2024/10/10 11:45:33.703]   File "/data/mci/778c9688944da7ebf97a2e5c75defa03/src/pymongo/asynchronous/mongo_client.py", line 1599, in _checkout
 [2024/10/10 11:45:33.703]     async with await server.checkout(handler=err_handler) as conn:
 [2024/10/10 11:45:33.703]   File "/opt/python/3.10/lib/python3.10/contextlib.py", line 199, in __aenter__
 [2024/10/10 11:45:33.703]     return await anext(self.gen)
 [2024/10/10 11:45:33.703]   File "/data/mci/778c9688944da7ebf97a2e5c75defa03/src/pymongo/asynchronous/pool.py", line 1342, in checkout
 [2024/10/10 11:45:33.703]     conn = await self._get_conn(checkout_started_time, handler=handler)
 [2024/10/10 11:45:33.703]   File "/data/mci/778c9688944da7ebf97a2e5c75defa03/src/pymongo/asynchronous/pool.py", line 1441, in _get_conn
 [2024/10/10 11:45:33.703]     raise _PoolClosedError(
 [2024/10/10 11:45:33.703] pymongo.asynchronous.pool._PoolClosedError: Attempted to check out a connection from closed connection pool
 [2024/10/10 11:45:33.713] test/asynchronous/test_client.py::TestClient::test_process_periodic_tasks PASSED [  4%]
 [2024/10/10 11:45:33.724] test/asynchronous/test_client.py::TestClient::test_repr PASSED           [  4%]
 [2024/10/10 11:45:33.729] test/asynchronous/test_client.py::TestClient::test_reset_during_update_pool SKIPPED [  4%]
 [2024/10/10 11:45:33.740] test/asynchronous/test_client.py::TestClient::test_server_selection_timeout PASSED [  4%]
 [2024/10/10 11:45:33.915] test/asynchronous/test_client.py::TestClient::test_service_name_from_kwargs PASSED [  4%]
 [2024/10/10 11:45:33.920] test/asynchronous/test_client.py::TestClient::test_sigstop_sigcont SKIPPED [  4%]
 [2024/10/10 11:45:33.926] test/asynchronous/test_client.py::TestClient::test_small_heartbeat_frequency_ms PASSED [  4%]

Another issue a test teardown times out after blocking for 25 minutes:

 [2024/10/10 11:47:16.935] test/asynchronous/test_retryable_writes.py::TestRetryableWrites::test_server_selection_timeout_not_retried PASSED [ 12%]
 [2024/10/10 11:47:17.181] test/asynchronous/test_retryable_writes.py::TestRetryableWrites::test_supported_single_statement_no_retry PASSED [ 12%]
 [2024/10/10 12:12:17.181] Timeout (0:25:00)!
 [2024/10/10 12:12:17.181] Thread 0x00007fc1ee7fd700 (most recent call first):
 [2024/10/10 12:12:17.181]   File "/opt/python/3.10/lib/python3.10/concurrent/futures/thread.py", line 81 in _worker
 [2024/10/10 12:12:17.181]   File "/opt/python/3.10/lib/python3.10/threading.py", line 953 in run
 [2024/10/10 12:12:17.181]   File "/opt/python/3.10/lib/python3.10/threading.py", line 1016 in _bootstrap_inner
 [2024/10/10 12:12:17.181]   File "/opt/python/3.10/lib/python3.10/threading.py", line 973 in _bootstrap
 [2024/10/10 12:12:17.181] Thread 0x00007fc1edffc700 (most recent call first):
 [2024/10/10 12:12:17.181]   File "/opt/python/3.10/lib/python3.10/concurrent/futures/thread.py", line 81 in _worker
 [2024/10/10 12:12:17.181]   File "/opt/python/3.10/lib/python3.10/threading.py", line 953 in run
 [2024/10/10 12:12:17.181]   File "/opt/python/3.10/lib/python3.10/threading.py", line 1016 in _bootstrap_inner
 [2024/10/10 12:12:17.181]   File "/opt/python/3.10/lib/python3.10/threading.py", line 973 in _bootstrap
 [2024/10/10 12:12:17.181] Thread 0x00007fc1ed4fe700 (most recent call first):
 [2024/10/10 12:12:17.181]   File "/opt/python/3.10/lib/python3.10/concurrent/futures/thread.py", line 81 in _worker
 [2024/10/10 12:12:17.181]   File "/opt/python/3.10/lib/python3.10/threading.py", line 953 in run
 [2024/10/10 12:12:17.181]   File "/opt/python/3.10/lib/python3.10/threading.py", line 1016 in _bootstrap_inner
 [2024/10/10 12:12:17.181]   File "/opt/python/3.10/lib/python3.10/threading.py", line 973 in _bootstrap
 [2024/10/10 12:12:17.181] Thread 0x00007fc21ce01700 (most recent call first):
 [2024/10/10 12:12:17.181]   File "/opt/python/3.10/lib/python3.10/concurrent/futures/thread.py", line 81 in _worker
 [2024/10/10 12:12:17.181]   File "/opt/python/3.10/lib/python3.10/threading.py", line 953 in run
 [2024/10/10 12:12:17.181]   File "/opt/python/3.10/lib/python3.10/threading.py", line 1016 in _bootstrap_inner
 [2024/10/10 12:12:17.181]   File "/opt/python/3.10/lib/python3.10/threading.py", line 973 in _bootstrap
 [2024/10/10 12:12:17.181] Thread 0x00007fc21d602700 (most recent call first):
 [2024/10/10 12:12:17.181]   File "/opt/python/3.10/lib/python3.10/concurrent/futures/thread.py", line 81 in _worker
 [2024/10/10 12:12:17.181]   File "/opt/python/3.10/lib/python3.10/threading.py", line 953 in run
 [2024/10/10 12:12:17.181]   File "/opt/python/3.10/lib/python3.10/threading.py", line 1016 in _bootstrap_inner
 [2024/10/10 12:12:17.181]   File "/opt/python/3.10/lib/python3.10/threading.py", line 973 in _bootstrap
 [2024/10/10 12:12:17.181] Thread 0x00007fc21de03700 (most recent call first):
 [2024/10/10 12:12:17.181]   File "/opt/python/3.10/lib/python3.10/concurrent/futures/thread.py", line 81 in _worker
 [2024/10/10 12:12:17.181]   File "/opt/python/3.10/lib/python3.10/threading.py", line 953 in run
 [2024/10/10 12:12:17.181]   File "/opt/python/3.10/lib/python3.10/threading.py", line 1016 in _bootstrap_inner
 [2024/10/10 12:12:17.181]   File "/opt/python/3.10/lib/python3.10/threading.py", line 973 in _bootstrap
 [2024/10/10 12:12:17.181] Thread 0x00007fc21e604700 (most recent call first):
 [2024/10/10 12:12:17.181]   File "/opt/python/3.10/lib/python3.10/concurrent/futures/thread.py", line 81 in _worker
 [2024/10/10 12:12:17.181]   File "/opt/python/3.10/lib/python3.10/threading.py", line 953 in run
 [2024/10/10 12:12:17.181]   File "/opt/python/3.10/lib/python3.10/threading.py", line 1016 in _bootstrap_inner
 [2024/10/10 12:12:17.181]   File "/opt/python/3.10/lib/python3.10/threading.py", line 973 in _bootstrap
 [2024/10/10 12:12:17.181] Thread 0x00007fc22ce64740 (most recent call first):
 [2024/10/10 12:12:17.181]   File "/opt/python/3.10/lib/python3.10/selectors.py", line 469 in select
 [2024/10/10 12:12:17.181]   File "/opt/python/3.10/lib/python3.10/asyncio/base_events.py", line 1871 in _run_once
 [2024/10/10 12:12:17.181]   File "/opt/python/3.10/lib/python3.10/asyncio/base_events.py", line 603 in run_forever
 [2024/10/10 12:12:17.181]   File "/opt/python/3.10/lib/python3.10/asyncio/base_events.py", line 636 in run_until_complete
 [2024/10/10 12:12:17.181]   File "/opt/python/3.10/lib/python3.10/unittest/async_case.py", line 136 in _tearDownAsyncioLoop
 [2024/10/10 12:12:17.181]   File "/opt/python/3.10/lib/python3.10/unittest/async_case.py", line 161 in run
 [2024/10/10 12:12:17.181]   File "/opt/python/3.10/lib/python3.10/unittest/case.py", line 650 in __call__
 [2024/10/10 12:12:17.181]   File "/home/ec2-user/.local/share/hatch/env/virtual/pymongo/Bgw-_9SP/test/lib/python3.10/site-packages/_pytest/unittest.py", line 332 in runtest
 [2024/10/10 12:12:17.181]   File "/home/ec2-user/.local/share/hatch/env/virtual/pymongo/Bgw-_9SP/test/lib/python3.10/site-packages/_pytest/runner.py", line 174 in pytest_runtest_call
 [2024/10/10 12:12:17.181]   File "/home/ec2-user/.local/share/hatch/env/virtual/pymongo/Bgw-_9SP/test/lib/python3.10/site-packages/pluggy/_callers.py", line 103 in _multicall
 [2024/10/10 12:12:17.181]   File "/home/ec2-user/.local/share/hatch/env/virtual/pymongo/Bgw-_9SP/test/lib/python3.10/site-packages/pluggy/_manager.py", line 120 in _hookexec
 [2024/10/10 12:12:17.181]   File "/home/ec2-user/.local/share/hatch/env/virtual/pymongo/Bgw-_9SP/test/lib/python3.10/site-packages/pluggy/_hooks.py", line 513 in __call__
 [2024/10/10 12:12:17.181]   File "/home/ec2-user/.local/share/hatch/env/virtual/pymongo/Bgw-_9SP/test/lib/python3.10/site-packages/_pytest/runner.py", line 242 in <lambda>
 [2024/10/10 12:12:17.181]   File "/home/ec2-user/.local/share/hatch/env/virtual/pymongo/Bgw-_9SP/test/lib/python3.10/site-packages/_pytest/runner.py", line 341 in from_call
 [2024/10/10 12:12:17.181]   File "/home/ec2-user/.local/share/hatch/env/virtual/pymongo/Bgw-_9SP/test/lib/python3.10/site-packages/_pytest/runner.py", line 241 in call_and_report
 [2024/10/10 12:12:17.181]   File "/home/ec2-user/.local/share/hatch/env/virtual/pymongo/Bgw-_9SP/test/lib/python3.10/site-packages/_pytest/runner.py", line 132 in runtestprotocol
 [2024/10/10 12:12:17.181]   File "/home/ec2-user/.local/share/hatch/env/virtual/pymongo/Bgw-_9SP/test/lib/python3.10/site-packages/_pytest/runner.py", line 113 in pytest_runtest_protocol
 [2024/10/10 12:12:17.181]   File "/home/ec2-user/.local/share/hatch/env/virtual/pymongo/Bgw-_9SP/test/lib/python3.10/site-packages/pluggy/_callers.py", line 103 in _multicall
 [2024/10/10 12:12:17.181]   File "/home/ec2-user/.local/share/hatch/env/virtual/pymongo/Bgw-_9SP/test/lib/python3.10/site-packages/pluggy/_manager.py", line 120 in _hookexec
 [2024/10/10 12:12:17.181]   File "/home/ec2-user/.local/share/hatch/env/virtual/pymongo/Bgw-_9SP/test/lib/python3.10/site-packages/pluggy/_hooks.py", line 513 in __call__
 [2024/10/10 12:12:17.181]   File "/home/ec2-user/.local/share/hatch/env/virtual/pymongo/Bgw-_9SP/test/lib/python3.10/site-packages/_pytest/main.py", line 362 in pytest_runtestloop
 [2024/10/10 12:12:17.181]   File "/home/ec2-user/.local/share/hatch/env/virtual/pymongo/Bgw-_9SP/test/lib/python3.10/site-packages/pluggy/_callers.py", line 103 in _multicall
 [2024/10/10 12:12:17.181]   File "/home/ec2-user/.local/share/hatch/env/virtual/pymongo/Bgw-_9SP/test/lib/python3.10/site-packages/pluggy/_manager.py", line 120 in _hookexec
 [2024/10/10 12:12:17.181]   File "/home/ec2-user/.local/share/hatch/env/virtual/pymongo/Bgw-_9SP/test/lib/python3.10/site-packages/pluggy/_hooks.py", line 513 in __call__
 [2024/10/10 12:12:17.181]   File "/home/ec2-user/.local/share/hatch/env/virtual/pymongo/Bgw-_9SP/test/lib/python3.10/site-packages/_pytest/main.py", line 337 in _main
 [2024/10/10 12:12:17.181]   File "/home/ec2-user/.local/share/hatch/env/virtual/pymongo/Bgw-_9SP/test/lib/python3.10/site-packages/_pytest/main.py", line 283 in wrap_session
 [2024/10/10 12:12:17.181]   File "/home/ec2-user/.local/share/hatch/env/virtual/pymongo/Bgw-_9SP/test/lib/python3.10/site-packages/_pytest/main.py", line 330 in pytest_cmdline_main
 [2024/10/10 12:12:17.181]   File "/home/ec2-user/.local/share/hatch/env/virtual/pymongo/Bgw-_9SP/test/lib/python3.10/site-packages/pluggy/_callers.py", line 103 in _multicall
 [2024/10/10 12:12:17.181]   File "/home/ec2-user/.local/share/hatch/env/virtual/pymongo/Bgw-_9SP/test/lib/python3.10/site-packages/pluggy/_manager.py", line 120 in _hookexec
 [2024/10/10 12:12:17.181]   File "/home/ec2-user/.local/share/hatch/env/virtual/pymongo/Bgw-_9SP/test/lib/python3.10/site-packages/pluggy/_hooks.py", line 513 in __call__
 [2024/10/10 12:12:17.181]   File "/home/ec2-user/.local/share/hatch/env/virtual/pymongo/Bgw-_9SP/test/lib/python3.10/site-packages/_pytest/config/__init__.py", line 175 in main
 [2024/10/10 12:12:17.181]   File "/home/ec2-user/.local/share/hatch/env/virtual/pymongo/Bgw-_9SP/test/lib/python3.10/site-packages/_pytest/config/__init__.py", line 201 in console_main
 [2024/10/10 12:12:17.181]   File "/home/ec2-user/.local/share/hatch/env/virtual/pymongo/Bgw-_9SP/test/lib/python3.10/site-packages/pytest/__main__.py", line 9 in <module>
 [2024/10/10 12:12:17.181]   File "/opt/python/3.10/lib/python3.10/runpy.py", line 86 in _run_code
 [2024/10/10 12:12:17.181]   File "/opt/python/3.10/lib/python3.10/runpy.py", line 196 in _run_module_as_main
 [2024/10/10 12:43:11.844] Hit exec timeout (1h0m0s).
 [2024/10/10 12:43:11.844] test/asynchronous/test_retryable_writes.py::TestRetryableWrites::test_supported_single_statement_supported_cluster
 [2024/10/10 12:43:11.904] Command 'shell.exec' in function 'run tests' (step 2.2 of 2) stopped early: context canceled.

I don't see any time outs like this happening on mainline so I think it's related to the changes here.

Both happened on execution 1 of this task:
https://spruce.mongodb.com/task/mongo_python_driver_tests_python_version_rhel8_test_ssl__platform~rhel8_auth_ssl~auth_ssl_python_version~3.10_coverage~coverage_test_latest_replica_set_patch_b111cbf5d5dab906a94d2c4b2a209cfde2971a94_67081c80118ee60008e370b5_24_10_10_18_27_14/logs?execution=0

@ShaneHarvey ShaneHarvey changed the base branch from master to async-improvements October 11, 2024 23:44
@ShaneHarvey ShaneHarvey marked this pull request as ready for review October 11, 2024 23:57
@sleepyStick sleepyStick merged commit ee18313 into mongodb:async-improvements Oct 12, 2024
26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants