58 lines
2.0 KiB
Python
58 lines
2.0 KiB
Python
"""Asyncio backports for Python 3.6 compatibility."""
|
|
from asyncio import coroutines, ensure_future
|
|
from asyncio.events import AbstractEventLoop
|
|
import concurrent.futures
|
|
import logging
|
|
import threading
|
|
from typing import Any, Callable, Coroutine
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
|
def fire_coroutine_threadsafe(coro: Coroutine, loop: AbstractEventLoop) -> None:
|
|
"""Submit a coroutine object to a given event loop.
|
|
|
|
This method does not provide a way to retrieve the result and
|
|
is intended for fire-and-forget use. This reduces the
|
|
work involved to fire the function on the loop.
|
|
"""
|
|
ident = loop.__dict__.get("_thread_ident")
|
|
if ident is not None and ident == threading.get_ident():
|
|
raise RuntimeError("Cannot be called from within the event loop")
|
|
|
|
if not coroutines.iscoroutine(coro):
|
|
raise TypeError("A coroutine object is required: %s" % coro)
|
|
|
|
def callback() -> None:
|
|
"""Handle the firing of a coroutine."""
|
|
ensure_future(coro, loop=loop)
|
|
|
|
loop.call_soon_threadsafe(callback)
|
|
|
|
|
|
def run_callback_threadsafe(
|
|
loop: AbstractEventLoop, callback: Callable, *args: Any
|
|
) -> concurrent.futures.Future:
|
|
"""Submit a callback object to a given event loop.
|
|
|
|
Return a concurrent.futures.Future to access the result.
|
|
"""
|
|
ident = loop.__dict__.get("_thread_ident")
|
|
if ident is not None and ident == threading.get_ident():
|
|
raise RuntimeError("Cannot be called from within the event loop")
|
|
|
|
future: concurrent.futures.Future = concurrent.futures.Future()
|
|
|
|
def run_callback() -> None:
|
|
"""Run callback and store result."""
|
|
try:
|
|
future.set_result(callback(*args))
|
|
except Exception as exc: # pylint: disable=broad-except
|
|
if future.set_running_or_notify_cancel():
|
|
future.set_exception(exc)
|
|
else:
|
|
_LOGGER.warning("Exception on lost future: ", exc_info=True)
|
|
|
|
loop.call_soon_threadsafe(run_callback)
|
|
return future
|