Commit 1ade70a1 authored by Jan Reimes's avatar Jan Reimes
Browse files

fix(whatthespec): handle asyncio.run() called from running event loop

resolve_via_whatthespec() uses asyncio.run() to resolve the meeting
ID from the DB.  When called from an async context (e.g. add-members
--kind tdocs), asyncio.run() raises RuntimeError because a loop is
already running, leaving the coroutine unawaited and meeting_id
silently unset.

Fix: detect a running loop via asyncio.get_running_loop() and, when
one is present, run the coroutine in a ThreadPoolExecutor thread
(which owns its own event loop).  Falls back to asyncio.run() in
plain sync contexts.
parent 6aaa3b45
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ from the whatthespec.net community API.
from __future__ import annotations

import asyncio
import concurrent.futures
from pathlib import Path

import requests
@@ -83,6 +84,14 @@ def resolve_via_whatthespec(
        async with MeetingDatabase(manager.db_file) as db:
            return await db.resolve_meeting_id(meeting_name) or 0

    # asyncio.run() cannot be called from within a running event loop (e.g. when
    # this sync function is invoked from an async caller).  Run in a thread that
    # owns its own event loop to stay safe in both contexts.
    try:
        asyncio.get_running_loop()
        with concurrent.futures.ThreadPoolExecutor(max_workers=1) as pool:
            meeting_id = pool.submit(asyncio.run, resolve_meeting_id_async()).result()
    except RuntimeError:
        meeting_id = asyncio.run(resolve_meeting_id_async())

    metadata = TDocMetadata(