Coverage for /usr/local/lib/python3.12/site-packages/prefect/_internal/concurrency/__init__.py: 100%
2 statements
« prev ^ index » next coverage.py v7.10.6, created at 2025-12-05 11:21 +0000
« prev ^ index » next coverage.py v7.10.6, created at 2025-12-05 11:21 +0000
1"""
2This module implements management of concurrency with a focus on seamless handling of
3both asynchronous and synchronous calls.
5Much of the complexity managed here arises from ensuring that a thread of execution is
6not blocked.
8The main data structure is a `Call` which is created from a function call capturing
9local context variables. The call is then submitted to run somewhere via a `Portal`.
10The primary portal used is the `WorkerThread`, which executes work on a thread running
11concurrently to the one that created the call. A singleton `EventLoopThread` portal
12is also used to schedule work on a dedicated event loop.
14The result of the call can be retrieved asynchronously using `Call.result()`. Behind
15the scenes, a `Future` is used to report the result of the call. Retrieving the result
16of a call is a blocking operation.
18Sometimes, it is important not to block the current thread while retrieving the result
19of a call. For this purpose, there is the `Waiter`. Waiters attach to a call and provide
20a `Waiter.wait()` method to wait for the call to complete. Instead of just blocking, the
21waiter watches a queue for calls to execute. Waiters implement the portal interface
22allowing calls to be submitted to its queue. This pattern is most common when a call
23running on a worker thread needs to schedule work back on the main thread.
25A possible scenario is as follows:
27- The main thread submits a call to a worker thread
28- The main thread uses a waiter to wait for the call to finish
29- The call does some work on the worker thread
30- The call reaches a point where it needs to run a call on the main thread
31- The call submits a callback to the waiter and waits for the callback's result
32- The waiter on the main thread runs the callback
34In most cases, a consumer of these utilities will not need to be aware of these details.
35Instead, a simple API is exposed in the `concurrency.api` module. The API is split into
36`api.from_sync` and `api.from_async` for use from synchronous and asynchronous contexts
37respectively.
38"""
40import prefect._internal._logging 1a
42logger = prefect._internal._logging.logger.getChild("concurrency") 1a