async_sync.py 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. """异步/同步桥接 —— anyio 线程调度与超时控制工具."""
  2. from __future__ import annotations
  3. import asyncio
  4. from typing import Any
  5. def _run_loop_until_complete(loop: asyncio.AbstractEventLoop, coro: Any) -> Any:
  6. try:
  7. return loop.run_until_complete(coro)
  8. except asyncio.CancelledError as e:
  9. raise RuntimeError("search_cancelled") from e
  10. def run_coroutine_sync(coro: Any, *, op_name: str) -> Any:
  11. try:
  12. running_loop = asyncio.get_running_loop()
  13. except RuntimeError:
  14. running_loop = None
  15. if running_loop is not None:
  16. raise RuntimeError(f"{op_name} called inside running event loop")
  17. try:
  18. loop = asyncio.get_event_loop()
  19. except RuntimeError:
  20. loop = None
  21. if loop is not None:
  22. if loop.is_running():
  23. try:
  24. import nest_asyncio
  25. nest_asyncio.apply()
  26. except Exception as e:
  27. raise RuntimeError(
  28. f"{op_name} called inside running event loop; "
  29. "install nest_asyncio or refactor call path to await the async call."
  30. ) from e
  31. return _run_loop_until_complete(loop, coro)
  32. new_loop = asyncio.new_event_loop()
  33. try:
  34. asyncio.set_event_loop(new_loop)
  35. return _run_loop_until_complete(new_loop, coro)
  36. finally:
  37. try:
  38. new_loop.close()
  39. finally:
  40. asyncio.set_event_loop(None)