Mercurial > code > home > repos > light9
comparison blender/asyncio_thread.py @ 2454:405abed9a45c
fix up asyncio-in-bg-thread sorcery
author | drewp@bigasterisk.com |
---|---|
date | Mon, 19 May 2025 21:25:32 -0700 |
parents | b23afde50bc2 |
children |
comparison
equal
deleted
inserted
replaced
2453:b23afde50bc2 | 2454:405abed9a45c |
---|---|
1 import asyncio | 1 import asyncio |
2 from threading import Thread | 2 import sys |
3 from threading import Thread, get_ident | |
4 import time | |
3 from typing import Coroutine | 5 from typing import Coroutine |
4 | 6 |
5 | 7 |
8 def log(msg): | |
9 try: | |
10 rl = hex(id(asyncio.get_running_loop())) | |
11 except RuntimeError: | |
12 rl = '(no loop ----)' | |
13 sys.stderr.write(f"thread={hex(get_ident())} loop={rl} {msg}\n") | |
14 | |
15 | |
6 def startLoopInThread(task: Coroutine) -> asyncio.AbstractEventLoop: | 16 def startLoopInThread(task: Coroutine) -> asyncio.AbstractEventLoop: |
17 """ | |
18 run a new event loop in a background thread. `task` is run in the new loop. | |
19 Caller should use this (from fg thread) to run further tasks: | |
20 asyncio.run_coroutine_threadsafe(task, returned_loop) | |
7 | 21 |
8 def start_background_loop(loop: asyncio.AbstractEventLoop) -> None: | 22 """ |
9 asyncio.set_event_loop(loop) | 23 log('🚋4 startLoopInThread enter ') |
10 loop.run_forever() | 24 loops = [] |
11 | 25 |
12 loop = asyncio.new_event_loop() | 26 def start_background_loop() -> None: |
13 t = Thread(target=start_background_loop, args=(loop,), daemon=True) | 27 |
28 async def forever(): | |
29 log('🚋6 log_loop') | |
30 loops.append(asyncio.get_running_loop()) | |
31 while True: | |
32 await asyncio.sleep(100) | |
33 | |
34 log('🚋5 make asyncio loop') | |
35 asyncio.run(forever()) | |
36 log('🚋19 start_background_loop done') | |
37 | |
38 t = Thread(target=start_background_loop, daemon=True) | |
14 t.start() | 39 t.start() |
40 while not loops: | |
41 time.sleep(.1) | |
42 loop = loops[0] | |
43 log('🚋7 loop has started in thread') | |
44 | |
15 asyncio.run_coroutine_threadsafe(task, loop) | 45 asyncio.run_coroutine_threadsafe(task, loop) |
46 log('🚋8 started task') | |
47 | |
48 log('🚋9 startLoopInThread exit') | |
16 return loop | 49 return loop |