1919from collections .abc import Awaitable , Generator
2020from concurrent .futures import Future
2121from contextlib import contextmanager
22- from typing import Any , TypeAlias , TypeVar
22+ from typing import Any , TypeVar
2323
2424_T = TypeVar ("_T" )
2525
26- _FutureLike : TypeAlias = asyncio .Future [_T ] | Awaitable [_T ]
26+ type _FutureLike [ _T ] = asyncio .Future [_T ] | Awaitable [_T ]
2727
2828__all__ = ["threaded_loop" ]
2929
@@ -52,12 +52,14 @@ def future_done_callback(_f: Future[Any]) -> object:
5252 return future .result ()
5353
5454
55- def run_forever (loop : asyncio .AbstractEventLoop ) -> None :
55+ def run_forever (loop : asyncio .AbstractEventLoop , use_eager_task_factory : bool , / ) -> None :
5656 asyncio .set_event_loop (loop )
57+ if use_eager_task_factory :
58+ loop .set_task_factory (asyncio .eager_task_factory )
5759 try :
5860 loop .run_forever ()
5961 finally :
60- loop .run_until_complete (asyncio .sleep (0.05 ))
62+ loop .run_until_complete (asyncio .sleep (0 ))
6163 tasks : set [asyncio .Task [Any ]] = {t for t in asyncio .all_tasks (loop ) if not t .done ()}
6264 for t in tasks :
6365 t .cancel ()
@@ -83,7 +85,7 @@ def run_forever(loop: asyncio.AbstractEventLoop) -> None:
8385
8486
8587@contextmanager
86- def threaded_loop () -> Generator [LoopWrapper , None , None ]:
88+ def threaded_loop (* , use_eager_task_factory : bool = True ) -> Generator [LoopWrapper , None , None ]:
8789 """Starts an event loop on a background thread,
8890 and yields an object with scheduling methods for interacting with
8991 the loop.
@@ -92,7 +94,7 @@ def threaded_loop() -> Generator[LoopWrapper, None, None]:
9294 loop = asyncio .new_event_loop ()
9395 thread = None
9496 try :
95- thread = threading .Thread (target = run_forever , args = (loop ,))
97+ thread = threading .Thread (target = run_forever , args = (loop , use_eager_task_factory ))
9698 thread .start ()
9799 yield LoopWrapper (loop )
98100 finally :
0 commit comments