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

1""" 

2This module implements management of concurrency with a focus on seamless handling of 

3both asynchronous and synchronous calls. 

4 

5Much of the complexity managed here arises from ensuring that a thread of execution is 

6not blocked. 

7 

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. 

13 

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. 

17 

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. 

24 

25A possible scenario is as follows: 

26 

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 

33 

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""" 

39 

40import prefect._internal._logging 1a

41 

42logger = prefect._internal._logging.logger.getChild("concurrency") 1a