def run_coroutine_threadsafe(coro, loop): """Submit a coroutine 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') if not coroutines.iscoroutine(coro): raise TypeError('A coroutine object is required') future = concurrent.futures.Future() def callback(): """Handle the call to the coroutine.""" try: # pylint: disable=deprecated-method _chain_future(ensure_future(coro, loop=loop), future) # pylint: disable=broad-except except Exception as exc: 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(callback) return future
def send(self, packet: dict): packet['from'] = self._host_id func = getattr(self, '_' + packet['type'] + '_sender') wrapper_func = func if not iscoroutine(func): wrapper_func = coroutine(func) asyncio.ensure_future(wrapper_func(packet))
def run_coroutine_threadsafe( coro: Union[Coroutine, Generator], loop: AbstractEventLoop) -> concurrent.futures.Future: """Submit a coroutine 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') if not coroutines.iscoroutine(coro): raise TypeError('A coroutine object is required') future = concurrent.futures.Future() # type: concurrent.futures.Future def callback() -> None: """Handle the call to the coroutine.""" try: _chain_future(ensure_future(coro, loop=loop), future) 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(callback) return future
def _check_not_coroutine(self, callback, name): """Check whether the given callback is a coroutine or not.""" from asyncio import coroutines if coroutines.iscoroutine(callback) or coroutines.iscoroutinefunction( callback): raise TypeError("coroutines cannot be used with {}()".format(name))
def connection_made(self, transport): self._stream_reader.set_transport(transport) if self._client_connected_cb is not None: self._stream_writer = SaltChannelStreamWriter( transport, self, self._stream_reader, self._loop) res = self._client_connected_cb(self._stream_reader, self._stream_writer) if coroutines.iscoroutine(res): self._loop.create_task(res)
def async_fire_and_forget(coro, loop): """Run some code in the core event loop without a result""" if not coroutines.iscoroutine(coro): raise TypeError(('A coroutine object is required: {}').format(coro)) def callback(): """Handle the firing of a coroutine.""" ensure_future(coro, loop=loop) loop.call_soon_threadsafe(callback) return
async def send_packet(self, data): await self._can_write.wait() # When a socket is closed on the other side, and due to the nature of # how asyncio is doing writes, we never receive an exception. So, # instead, check every time we send something if we are not closed. # If we are, inform our caller which should stop transmitting. if self.transport.is_closing(): raise SocketClosed res = self.transport.write(data) if iscoroutine(res): await res
async def download(self, out_steam, binary: bool = True) -> None: """ Downloads this resource and writes it to the specified stream. :param out_steam: the stream to write to output to :param binary: whether the data should not be decoded """ async with aiohttp.ClientSession() as s: async with s.get( f"{self.file_url}?token={self.moodle.token}") as r: data = await r.read() if not binary: data = data.decode() res = out_steam.write(data) if iscoroutine(res): await res
def actual_decorator(func: callable): if iscoroutine(func) or iscoroutinefunction(func): @functools.wraps(func) @astd.lru_cache(maxsize=max_size) async def deco(*args, **kwargs): return await func(*args, **kwargs) else: @functools.wraps(func) @functools.lru_cache(maxsize=max_size) def deco(*args, **kwargs): return func(*args, **kwargs) return deco
def native_run(main, *, debug=False): # Snatched from Python 3.7 from asyncio import coroutines from asyncio import events from asyncio import tasks def _cancel_all_tasks(loop): to_cancel = all_tasks(loop) if not to_cancel: return for task in to_cancel: task.cancel() loop.run_until_complete( tasks.gather(*to_cancel, loop=loop, return_exceptions=True)) for task in to_cancel: if task.cancelled(): continue if task.exception() is not None: loop.call_exception_handler({ 'message': 'unhandled exception during asyncio.run() shutdown', 'exception': task.exception(), 'task': task, }) if events._get_running_loop() is not None: raise RuntimeError( "asyncio.run() cannot be called from a running event loop") if not coroutines.iscoroutine(main): raise ValueError("a coroutine was expected, got {!r}".format(main)) loop = events.new_event_loop() try: events.set_event_loop(loop) loop.set_debug(debug) return loop.run_until_complete(main) finally: try: _cancel_all_tasks(loop) loop.run_until_complete(loop.shutdown_asyncgens()) finally: events.set_event_loop(None) loop.close()
def fire_coroutine_threadsafe(coro, loop): """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. """ if not coroutines.iscoroutine(coro): raise TypeError('A coroutine object is required: %s' % coro) def callback(): """Callback to fire coroutine.""" # pylint: disable=deprecated-method ensure_future(coro, loop=loop) loop.call_soon_threadsafe(callback) return
async def f_retry(self, *args, **kwargs): if not iscoroutine(func): f = coroutine(func) else: f = func mtries, mdelay = tries, delay while mtries > 1: try: return await f(self, *args, **kwargs) except exceptions: if logger: logger.info('Retrying %s after %s seconds', f.__name__, mdelay) sleep(mdelay) mtries -= 1 mdelay *= backoff return await f(self, *args, **kwargs)
def native_run(main: Awaitable[_T], *, debug: bool = False) -> _T: """Run a coroutine. This function runs the passed coroutine, taking care of managing the asyncio event loop and finalizing asynchronous generators. This function cannot be called when another asyncio event loop is running in the same thread. If debug is True, the event loop will be run in debug mode. This function always creates a new event loop and closes it at the end. It should be used as a main entry point for asyncio programs, and should ideally only be called once. Example: async def main(): await asyncio.sleep(1) print('hello') asyncio.run(main()) """ from asyncio import events, coroutines if events._get_running_loop() is not None: raise RuntimeError( "asyncio.run() cannot be called from a running event loop") if not coroutines.iscoroutine(main): raise ValueError("a coroutine was expected, got {!r}".format(main)) loop = events.new_event_loop() try: events.set_event_loop(loop) loop.set_debug(debug) return loop.run_until_complete(main) finally: try: _cancel_all_tasks(loop) loop.run_until_complete(loop.shutdown_asyncgens()) finally: events.set_event_loop(None) # type: ignore loop.close()
def async_run(main): """ A simplified version of Python 3.7+ run """ if events._get_running_loop() is not None: # pylint: disable=protected-access raise RuntimeError( "asyncio.run() cannot be called from a running event loop" ) if not coroutines.iscoroutine(main): raise ValueError("a coroutine was expected, got {!r}".format(main)) loop = events.new_event_loop() try: events.set_event_loop(loop) return loop.run_until_complete(main) finally: events.set_event_loop(None) loop.close()
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 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(main: Coroutine, *, debug: bool = False) -> int: """Performs the logic of running an automation's main coroutine and ensuring the exit code it returns is used as the processes exit code, as well as, properly shutting down the event loop :param main: An automation's main coroutine :param debug: Should the event loop be run in debug mode :return: The exit code returned by the automation's main coroutine """ if events._get_running_loop() is not None: raise RuntimeError( "run_automation() cannot be called from a running event loop") if not coroutines.iscoroutine(main): raise ValueError("a coroutine was expected, got {!r}".format(main)) loop = asyncio.get_event_loop() try: loop.set_debug(debug) result = loop.run_until_complete(main) logger.info(f"run_automation: exiting with code {result}") return result except Exception as e: logger.exception( "run_automation: While running an automation an exception was thrown", exc_info=e, ) return 2 except KeyboardInterrupt as e: logger.exception( "run_automation: While running an automation an KeyboardInterrupt happened", exc_info=e, ) return 0 finally: try: _cancel_all_tasks(loop) loop.run_until_complete(loop.shutdown_asyncgens()) except Exception: pass finally: loop.close()
def run_coroutine_threadsafe(coro, loop): """Submit a coroutine object to a given event loop. Return a concurrent.futures.Future to access the result. """ if not coroutines.iscoroutine(coro): raise TypeError('A coroutine object is required') future = concurrent.futures.Future() def callback(): """Callback to call the coroutine.""" try: # pylint: disable=deprecated-method _chain_future(ensure_future(coro, loop=loop), future) except Exception as exc: if future.set_running_or_notify_cancel(): future.set_exception(exc) raise loop.call_soon_threadsafe(callback) return future
def fire_coroutine_threadsafe(coro, loop): """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(): """Callback to fire coroutine.""" # pylint: disable=deprecated-method ensure_future(coro, loop=loop) loop.call_soon_threadsafe(callback) return
async def call_target(self, targetKey, *args, **kw): '''call Target @param conn: client connection @param targetKey: target ID @param data: client data ''' target = self.get_target(targetKey) self._lock.acquire() try: if not target: logger.warn('the command ' + str(targetKey) + ' not Found on service') return None result = target(targetKey, *args, **kw) if iscoroutine(result): result = await result logger.debug("call_target result:{}".format(result)) return result finally: self._lock.release()
def __init__(self, coro, *, loop=None, name=None, context=None): asyncio.futures._PyFuture.__init__(self, loop=loop) if self._source_traceback: del self._source_traceback[-1] if not coroutines.iscoroutine(coro): # raise after Future.__init__(), attrs are required for __del__ # prevent logging for pending task in __del__ self._log_destroy_pending = False raise TypeError(f"a coroutine was expected, got {coro!r}") if name is None: self._name = f'Task-{asyncio.tasks._task_name_counter()}' else: self._name = str(name) self._must_cancel = False self._fut_waiter = None self._coro = coro self._context = context if context is not None else copy_context() self._loop.call_soon(self.__step, context=self._context) asyncio._register_task(self)
def _check_not_coroutine(self, callback, name): from asyncio import coroutines if (coroutines.iscoroutine(callback) or coroutines.iscoroutinefunction(callback)): raise TypeError("coroutines cannot be used with {}()".format(name))
def _check_not_coroutine(self, callback, name): """Check whether the given callback is a coroutine or not.""" if (coroutines.iscoroutine(callback) or coroutines.iscoroutinefunction(callback)): raise TypeError("coroutines cannot be used with {}()".format(name))
import asyncio from asyncio.coroutines import iscoroutine import time def sync_worker(number, divider): print('Sync Worker started with values: {}/{}'.format(number, divider)) time.sleep(1) print(number / divider) @asyncio.coroutine def async_worker(number, divider): print('Async Worker started with values: {}/{}'.format(number, divider)) yield from asyncio.sleep(0) print(number / divider) sync_worker(30, 10) sync_worker(30, 10) print(iscoroutine(sync_worker)) print(iscoroutine(async_worker(10, 2))) event_loop = asyncio.get_event_loop() task_list = [ event_loop.create_task(async_worker(30, 10)), event_loop.create_task(async_worker(50, 25)) ] tasks = asyncio.wait(task_list) event_loop.run_until_complete(tasks) event_loop.close()