lib.AsyncRunner: Fix asyncio.Event() for Python 3.12+
All checks were successful
CI / Packaging - Kali Linux (pull_request) Successful in 4m33s
CI / Packaging - OpenSUSE Tumbleweed (pull_request) Successful in 4m15s
CI / Packaging test (pull_request) Successful in 0s
CI / Packaging - Kali Linux (push) Successful in 4m2s
CI / Packaging - OpenSUSE Tumbleweed (push) Successful in 3m53s
CI / Packaging test (push) Successful in 0s
All checks were successful
CI / Packaging - Kali Linux (pull_request) Successful in 4m33s
CI / Packaging - OpenSUSE Tumbleweed (pull_request) Successful in 4m15s
CI / Packaging test (pull_request) Successful in 0s
CI / Packaging - Kali Linux (push) Successful in 4m2s
CI / Packaging - OpenSUSE Tumbleweed (push) Successful in 3m53s
CI / Packaging test (push) Successful in 0s
AsyncRunner is currently unused. This bug was detected and fixed by AI. asyncio.Event() raises RuntimeError on Python 3.12+ when created outside a running event loop. It is created in the sync portion of loop_in_thread(), before the threaded loop is up. The fix is to move the Event creation inside the async main() coroutine and pass it back via a second future. It replaces the fragile as_completed loop with sequential result() calls, so failures are immediately visible rather than causing a silent thread hang. Assisted-by: unsloth/Qwen3.6-27B-MTP-GGUF:Q4_K_M with pi.dev v0.84.1 Signed-off-by: Jan Lindemann <jan@janware.com>
This commit is contained in:
parent
75b6603a3f
commit
ac35da6d9c
1 changed files with 10 additions and 12 deletions
|
|
@ -17,25 +17,23 @@ def loop_in_thread() -> Generator[asyncio.AbstractEventLoop, None, None]:
|
|||
loop_fut: concurrent.futures.Future[asyncio.AbstractEventLoop] = (
|
||||
concurrent.futures.Future()
|
||||
)
|
||||
|
||||
stop_event = asyncio.Event()
|
||||
stop_fut: concurrent.futures.Future[asyncio.Event] = (concurrent.futures.Future())
|
||||
|
||||
async def main() -> None:
|
||||
loop_fut.set_result(asyncio.get_running_loop())
|
||||
stop_event = asyncio.Event()
|
||||
stop_fut.set_result(stop_event)
|
||||
await stop_event.wait()
|
||||
|
||||
with concurrent.futures.ThreadPoolExecutor(max_workers = 1) as tpe:
|
||||
complete_fut = tpe.submit(asyncio.run, main())
|
||||
|
||||
for fut in concurrent.futures.as_completed((loop_fut, complete_fut)):
|
||||
if fut is loop_fut:
|
||||
loop = loop_fut.result()
|
||||
try:
|
||||
yield loop
|
||||
finally:
|
||||
loop.call_soon_threadsafe(stop_event.set)
|
||||
else:
|
||||
fut.result()
|
||||
loop = loop_fut.result()
|
||||
stop_event = stop_fut.result()
|
||||
try:
|
||||
yield loop
|
||||
finally:
|
||||
loop.call_soon_threadsafe(stop_event.set)
|
||||
complete_fut.result()
|
||||
|
||||
class AsyncRunner:
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue