def current_task( loop: Optional[asyncio.AbstractEventLoop]=None ) -> 'asyncio.Task[Any]': if PY_37: return asyncio.current_task(loop=loop) # type: ignore else: return asyncio.Task.current_task(loop=loop)
async def test_dispatch_event_cancel(self, source): """Test that dispatching an event when there are no listeners will still work.""" source.event_a.connect(lambda event: None) future = source.event_a.dispatch() future.cancel() task = next(t for t in all_tasks() if t is not current_task()) await task
async def amain(*, args, prog): params = docopt.docopt( __doc__.replace("\t", " " * 4).format(prog=os.path.basename(prog)), argv=args, help=True, version=True, options_first=False ) url = params.pop("URL") assert not params, params log = asyncio.Queue() pending_tasks = [] printer_task = asyncio.create_task( printer(queue=log, fo=sys.stdout) ) git = Git(output_queue=log, git_path="git") out = await git.credential("fill", { "url": url, }) await log.put(out) await asyncio.gather(*pending_tasks) current_task, all_tasks = (asyncio.current_task(), asyncio.all_tasks()) assert {current_task, printer_task} == all_tasks, (current_task, all_tasks) await log.put(None) await printer_task
def current_task(loop: OptLoop = None) -> 'Task[Any]': _loop = loop or asyncio.get_event_loop() # type: Loop if hasattr(asyncio, 'current_task'): t = asyncio.current_task(loop=_loop) else: t = asyncio.Task.current_task(loop=_loop) if t is None: raise RuntimeError('Loop is not running') return t
def current_task(loop: asyncio.AbstractEventLoop) -> asyncio.Task: if PY_37: task = asyncio.current_task(loop=loop) # type: ignore else: task = asyncio.Task.current_task(loop=loop) if task is None: # this should be removed, tokio must use register_task and family API if hasattr(loop, 'current_task'): task = loop.current_task() # type: ignore return task
def _task_scope(): task = asyncio.current_task() scope = getattr(task, '_syn_scope', None) # no need to lock because it's per-task... if scope is None: scope = Scope(globscope) task._syn_scope = scope return scope
def current_task(loop): if PY_37: task = asyncio.current_task(loop=loop) else: task = asyncio.Task.current_task(loop=loop) if task is None: # this should be removed, tokio must use register_task and family API if hasattr(loop, 'current_task'): task = loop.current_task() return task
def varinit(task=None): ''' Initializes (or re-initializes for testing purposes) all of a task's task-local variables Precondition: If task is None, this must be called from task context ''' if task is None: task = asyncio.current_task() taskvars = {} task._syn_taskvars = taskvars return taskvars
async def shutdown(loop, signal=None): if signal: logging.info(f"Received exit signal {signal.name}...") logging.info("Closing database connections") logging.info("Nacking outstanding messages") tasks = [t for t in asyncio.all_tasks() if t is not asyncio.current_task()] [task.cancel() for task in tasks] logging.info("Cancelling outstanding tasks") await asyncio.gather(*tasks, return_exceptions=True) logging.info(f"Flushing metrics") loop.stop()
async def removetasks(loop): tasks = [t for t in asyncio.all_tasks() if t is not asyncio.current_task()] for task in tasks: # skipping over shielded coro still does not help if task._coro.__name__ == "cant_stop_me": continue task.cancel() print("Cancelling outstanding tasks") await asyncio.gather(*tasks, return_exceptions=True) loop.stop()
async def handle_connection(self, r, w): peername = w.get_extra_info('peername') asyncio_utils.set_task_debug_info( asyncio.current_task(), name=f"Proxyserver.handle_connection", client=peername, ) handler = ProxyConnectionHandler(self.master, r, w, self.options) self._connections[peername] = handler try: await handler.handle_client() finally: del self._connections[peername]
def _run_until_done(coro): """execute coroutine, when already in the event loop""" loop = asyncio.get_running_loop() task = asyncio.current_task() asyncio.tasks._unregister_task(task) current_task = asyncio.tasks._current_tasks.get(loop) assert task == current_task del asyncio.tasks._current_tasks[loop] runner = loop.create_task(coro) while not runner.done(): loop._run_once() asyncio.tasks._current_tasks[loop] = task return runner.result()
async def shutdown(loop): try: all_tasks = asyncio.all_tasks() current_task = asyncio.current_task() except AttributeError: all_tasks = asyncio.Task.all_tasks() current_task = asyncio.tasks.Task.current_task() tasks = [task for task in all_tasks if task is not current_task] list(map(lambda task: task.cancel(), tasks)) await asyncio.gather(*tasks, return_exceptions=True) loop.stop()
async def terminate_server(sig: int, loop: asyncio.AbstractEventLoop) -> None: if sig == signal.SIGINT and os.isatty(sys.stdout.fileno()): # Terminate the line containing ^C print() await asyncio.gather(*SHUTDOWN, return_exceptions=True) tasks = [t for t in asyncio.all_tasks() if t is not asyncio.current_task()] for task in tasks: task.cancel() await asyncio.gather(*tasks, return_exceptions=True) loop.stop()
async def stop(self) -> None: self.logger.info('shutting down...') self.shutdown_event.set() tasks = [ task for task in asyncio.all_tasks() if task is not asyncio.current_task() ] list(map(lambda task: task.cancel(), tasks)) await asyncio.gather(*tasks, return_exceptions=True) self.logger.info('shut down') self.loop.stop()
async def shutdown(signal, loop): """Cleanup tasks tied to the service's shutdown.""" print(f"Received exit signal {signal.name}...") print("Closing redis connections") print("Nacking outstanding messages") tasks = [t for t in asyncio.all_tasks() if t is not asyncio.current_task()] [task.cancel() for task in tasks] print(f"Cancelling {len(tasks)} outstanding tasks") await asyncio.gather(*tasks, return_exceptions=True) print(f"Flushing metrics") loop.stop()
async def shutdown_handler(red, signal_type=None): if signal_type: log.info("%s received. Quitting...", signal_type) exit_code = 0 else: log.info("Shutting down from unhandled exception") exit_code = 1 await red.logout() await red.loop.shutdown_asyncgens() pending = [t for t in asyncio.all_tasks() if t is not asyncio.current_task()] [task.cancel() for task in pending] await asyncio.gather(*pending, loop=red.loop, return_exceptions=True) sys.exit(exit_code)
async def background_stats(self, subs=[ "export", "discover", "interfaces", "system-stats", "num-routes", "config-change", "users" ]): # self- registering task task = asyncio.current_task() if task: await self.add_task('stats', task) with suppress(asyncio.CancelledError): async for payload in self.stats(subs): pass
def _get_task(self): try: # Prevent failure when run from a thread # without an event loop. loop = asyncio.get_event_loop() except RuntimeError: return None if hasattr(asyncio, 'current_task'): # Python 3.7+ return asyncio.current_task(loop=loop) else: # Python 3.6 and below return asyncio.Task.current_task(loop=loop)
async def shutdown(signal, loop): logging.info(f"Received exit signal {signal.name}...") logging.info("Closing database connections") logging.info("Nacking outstanding messages") tasks = [t for t in asyncio.all_tasks() if t is not asyncio.current_task()] for i, task in enumerate(tasks): task.cancel() logging.info("Cancelling outstanding tasks") await asyncio.gather(*tasks) loop.stop() logging.info("Shutdown complete.")
async def _target_consumer(): while True: async with _lock: await _lock.wait() _async_task_flag["consumer"].append(float(time.time())) if (PYTHON_MAJOR_VERSION, PYTHON_MINOR_VERSION) > (3, 6): _async_task_ids["consumer"] = str( id(asyncio.current_task())) else: _async_task_ids["consumer"] = str( id(asyncio.Task.current_task())) if len(_async_task_flag["producer"]) == 3: break
async def shutdown(signal, loop): """Cleanup tasks tied to the service's shutdown.""" logging.info(f'Received exit signal {signal.name}...') logging.info('Closing database connections') logging.info('Nacking outstanding messages') tasks = [t for t in asyncio.all_tasks() if t is not asyncio.current_task()] [task.cancel() for task in tasks] logging.info(f'Cancelling {len(tasks)} outstanding tasks') await asyncio.gather(*tasks) loop.stop() logging.info('Shutdown complete.')
async def _target_testing(): # Save a timestamp into list await _lock.acquire() await asyncio.sleep(_Sleep_Time) if (PYTHON_MAJOR_VERSION, PYTHON_MINOR_VERSION) > (3, 6): _async_task = asyncio.current_task( loop=asyncio.get_event_loop()) else: _async_task = asyncio.Task.current_task() _async_task_id = id(_async_task) _time = float(time.time()) _done_timestamp[_async_task_id] = _time _lock.release()
async def shutdown(): """ Shutdown actions """ # pylint:disable=import-outside-toplevel current_task = asyncio.current_task() other_tasks = [t for t in asyncio.all_tasks() if t is not current_task] LOGGER.info("Cancelling %s outstanding tasks", len(other_tasks)) for task in other_tasks: task.cancel() await DATABASE.disconnect() await asyncio.gather(*other_tasks, return_exceptions=True)
async def finalize() -> None: lock = asyncio.Lock() async with lock: if self.client.is_initialized: if self.stop_manual: await self.client.stop(block=False) else: await self.client.stop() for task in asyncio.all_tasks(): if task is not asyncio.current_task(): task.cancel() await self.loop.shutdown_asyncgens()
async def _target_producer(): for _ in range(3): await asyncio.sleep(_Sleep_Time) _thread_index = random.randrange(_Random_Start_Time, _Random_End_Time) _async_task_flag["producer"].append(_thread_index) if (PYTHON_MAJOR_VERSION, PYTHON_MINOR_VERSION) > (3, 6): _async_task_ids["producer"] = str( id(asyncio.current_task())) else: _async_task_ids["producer"] = str( id(asyncio.Task.current_task())) _lock.set()
def check_cancelled(): try: cancel_scope = _task_states[current_task()].cancel_scope except KeyError: return while cancel_scope: if cancel_scope.cancel_called: raise CancelledError elif cancel_scope.shield: return else: cancel_scope = cancel_scope._parent_scope
async def navigate(self, ctx, *, timeout=120, target=None): _bot = ctx.bot _loop = _bot.loop target = target or ctx.author if target.id in self.all_tasks: self.all_tasks.pop(target.id).cancel() self.all_tasks[target.id] = asyncio.current_task(loop=_loop) if ctx.channel.permissions_for(ctx.me).manage_messages: event = "reaction_add" handle_reaction = lambda m, r, u: _loop.create_task(try_it(m.remove_reaction(r, u))) else: event = "reaction_add_or_remove" handle_reaction = lambda m, r, u: None if self.first_page: embed = self.first_page elif self.container: embed = self.render() else: embed = next(iter(self.navigation.values()))() try: message = await ctx.send(embed=embed) except asyncio.CancelledError: return self.all_tasks.pop(target.id, None) if not self.navigation: return self.all_tasks.pop(target.id, None) rt = _loop.create_task(self.add_navigate_reactions(message)) try: while True: try: reaction, user = await _bot.wait_for( event, check=lambda r, u: target==u and r.emoji in self.navigation and r.message.id==message.id, timeout=timeout ) except asyncio.TimeoutError: return self.all_tasks.pop(target.id, None) embed = self.navigation[reaction.emoji]() if inspect.isawaitable(embed): embed = await embed if embed is not None: await message.edit(embed=embed) handle_reaction(message, reaction, user) else: return self.all_tasks.pop(target.id, None) except asyncio.CancelledError: rt.cancel() finally: _loop.create_task(try_it(message.clear_reactions()))
async def _stream_and_cache(self): """Stream data from upstream and cache them. The download and caching is done in the background, to prevent disconnecting clients from stopping it. """ client_session = aiotask_context.get('client_session') self.log.info('Caching upstream', url=self.url, path=self.path) queue = asyncio.Queue() fut_finished = asyncio.Future() cur_task = asyncio.current_task() async def _stream_queue(): while queue.qsize() or not fut_finished.done(): data = await queue.get() try: yield data finally: queue.task_done() async def _enqueue_upstream(): try: log.debug('Streaming from upstream into file and queue', file=self.path_preparing, url=self.url) async with aiofiles.open(self.path_preparing, 'xb') as f: async with client_session.get(self.url) as r: async for data, _ in r.content.iter_chunks(): await f.write(data) await queue.put(data) fut_finished.set_result(True) self.path_preparing.rename(self.path) self.log.info('Finished download', path=self.path) except (asyncio.CancelledError, IOError, Exception) as ex: # noqa: W0703 cur_task.cancel() # cleanup broken download self.log.error('Cleaning broken download', path=self.path_preparing, error=ex) try: self.path_preparing.unlink() except FileNotFoundError: pass # TODO use aiojobs ??? to cancel this future graceully # GeneratorExit asyncio.ensure_future(_enqueue_upstream()) async for data in _stream_queue(): yield data
async def cancel(self): if not self._cancel_called: self._cancel_called = True # Check if the host task should be cancelled if self._host_task is not current_task(): scope = get_cancel_scope(self._host_task) while scope and scope is not self: if scope.shield: break else: scope = scope._parent_scope else: self._host_task.cancel()
async def shutdown(signal, loop, board): # Shutdown teh telemtrix board await board.shutdown() # Stop the asyncio loop loop.stop() # Shutdown all tasks tasks = [t for t in asyncio.all_tasks() if t is not asyncio.current_task()] [task.cancel() for task in tasks] await asyncio.gather(*tasks, return_exceptions=True) # Exit exit(0)
async def shutdown(self, signal=None): """Cleanup tasks tied to the service's shutdown.""" if signal: logger.info(f"Received exit signal {signal.name}...") tasks = [ t for t in asyncio.all_tasks() if t is not asyncio.current_task() ] [task.cancel() for task in tasks] logger.info(f"Cancelling {len(tasks)} outstanding tasks") await asyncio.gather(*tasks, return_exceptions=True) self.loop.stop()
async def _shutdown(self, loop: asyncio.AbstractEventLoop, signal=None) -> None: if not self.running: raise RuntimeError("Cannot shutdown an assembly that is not running") if signal: self.logger.info(f"Received exit signal {signal.name}...") reason = signal.name if signal else "shutdown" # Shut down the servo runners, breaking active control loops if len(self.runners) == 1: self.logger.info(f"Shutting down servo...") else: self.logger.info(f"Shutting down {len(self.runners)} running servos...") for fut in asyncio.as_completed( list(map(lambda r: r.shutdown(reason=reason), self.runners)), timeout=30.0 ): try: await fut except Exception as error: self.logger.critical( f"Failed servo runner shutdown with error: {error}" ) # Shutdown the assembly and the servos it contains self.logger.debug("Dispatching shutdown event...") try: await self.assembly.shutdown() except Exception as error: self.logger.critical(f"Failed assembly shutdown with error: {error}") await asyncio.gather(self.progress_handler.shutdown(), return_exceptions=True) self.logger.remove(self.progress_handler_id) # Cancel any outstanding tasks -- under a clean, graceful shutdown this list will be empty # The shutdown of the assembly and the servo should clean up its tasks tasks = [t for t in asyncio.all_tasks() if t is not asyncio.current_task()] if len(tasks): [task.cancel() for task in tasks] self.logger.info(f"Cancelling {len(tasks)} outstanding tasks") self.logger.debug(f"Outstanding tasks: {devtools.pformat(tasks)}") await asyncio.gather(*tasks, return_exceptions=True) self.logger.info("Servo shutdown complete.") await asyncio.gather(self.logger.complete(), return_exceptions=True) self._running = False loop.stop()
async def shutdown(loop, signal=None, log=None): if signal and log: msg = f'{datetime.now()} Received exit signal {signal.name}...' log.warning(msg) tasks = [t for t in asyncio.all_tasks() if t is not asyncio.current_task()] for task in tasks: msg = f'{datetime.now()} Cancelling task {task.get_name()}...' logging.warning(msg) task.cancel() await asyncio.gather(*tasks, return_exceptions=True) loop.stop()
def __enter__(self) -> BaseTimerContext: task = asyncio.current_task(loop=self._loop) if task is None: raise RuntimeError( "Timeout context manager should be used " "inside a task" ) if self._cancelled: task.cancel() raise asyncio.TimeoutError from None self._tasks.append(task) return self
def current_task(loop=None): if loop is None: loop = asyncio.get_event_loop() if PY_37: task = asyncio.current_task(loop=loop) else: task = asyncio.Task.current_task(loop=loop) if task is None: # this should be removed, tokio must use register_task and family API if hasattr(loop, 'current_task'): task = loop.current_task() return task
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) try: self.task = task = asyncio.current_task() except RuntimeError: self.task = task = None if task: self.taskName = task.get_name() origin = f"[{self.threadName}::{self.taskName}] {self.name}" else: self.taskName = None origin = f"[{self.threadName}] {self.name}" self.origin = TruncateAfterMaxWidthString(origin)
def _release(self, lock_type: int) -> None: # assert lock_type in (self._RL, self._WL) me = asyncio.current_task(loop=self._loop) assert me is not None # nosec try: self._owning.remove((me, lock_type)) except ValueError: raise RuntimeError('Cannot release an un-acquired lock') if lock_type == self._RL: self._r_state -= 1 else: self._w_state -= 1 self._wake_up()
def _taskdict(task): ''' Note: No locking is provided. Under normal circumstances, like the other task is not running (e.g. this is running from the same event loop as the task) or task is the current task, this is fine. ''' if task is None: task = asyncio.current_task() assert task taskvars = getattr(task, '_syn_taskvars', None) if taskvars is None: taskvars = varinit(task) return taskvars
async def promote(self, name, user, info=None): ''' Promote the currently running task. ''' task = asyncio.current_task() synt = getattr(task, '_syn_task', None) if synt is not None: if synt.root is None: return synt synt.root.kids.pop(synt.iden) synt.root = None return synt return await s_task.Task.anit(self, task, name, user, info=info)
def _loop_monitor_thread(self): """ Thread responsible for checking current tasks that are taking too long to finish and printing the stack. DISCLAIMER/TODO: This is not free of race condition so it may show false positives. """ set_thread_name('loop_monitor') last = None while True: time.sleep(2) current = asyncio.current_task(loop=self.__loop) if current is None: last = None continue if last == current: frame = sys._current_frames()[self.__thread_id] stack = traceback.format_stack(frame, limit=-10) self.logger.warn(''.join(['Task seems blocked:\n'] + stack)) last = current
def schedCoro(self, coro): ''' Schedules a free-running coroutine to run on this base's event loop. Kills the coroutine if Base is fini'd. It does not pend on coroutine completion. Precondition: This function is *not* threadsafe and must be run on the Base's event loop Returns: asyncio.Task: An asyncio.Task object. ''' import synapse.lib.provenance as s_provenance # avoid import cycle if __debug__: assert s_coro.iscoro(coro) import synapse.lib.threads as s_threads # avoid import cycle assert s_threads.iden() == self.tid task = self.loop.create_task(coro) # In rare cases, (Like this function being triggered from call_soon_threadsafe), there's no task context if asyncio.current_task(): s_provenance.dupstack(task) def taskDone(task): self._active_tasks.remove(task) try: task.result() except asyncio.CancelledError: pass except Exception: logger.exception('Task scheduled through Base.schedCoro raised exception') self._active_tasks.add(task) task.add_done_callback(taskDone) return task
def current(): ''' Return the current synapse task. ''' task = asyncio.current_task() return getattr(task, '_syn_task', None)
def current_task(loop: Optional[asyncio.AbstractEventLoop]=None) -> asyncio.Task: # type: ignore # noqa # Return type is intentionly Generic here if PY_37: return asyncio.current_task(loop=loop) # type: ignore else: return asyncio.Task.current_task(loop=loop) # type: ignore
def _is_current_task(): # pragma: no cover import asyncio if sys.version_info >= (3, 7): return asyncio.current_task() is not None return asyncio.Task.current_task() is not None
def current_task(loop=None): if PY_37: return asyncio.current_task(loop=loop) else: return asyncio.Task.current_task(loop=loop)
async def async_handle(self): """Handle a websocket response.""" request = self.request wsock = self.wsock = web.WebSocketResponse(heartbeat=55) await wsock.prepare(request) self._logger.debug("Connected") # Py3.7+ if hasattr(asyncio, 'current_task'): # pylint: disable=no-member self._handle_task = asyncio.current_task() else: self._handle_task = asyncio.Task.current_task(loop=self.hass.loop) @callback def handle_hass_stop(event): """Cancel this connection.""" self._cancel() unsub_stop = self.hass.bus.async_listen( EVENT_HOMEASSISTANT_STOP, handle_hass_stop) self._writer_task = self.hass.async_create_task(self._writer()) auth = AuthPhase(self._logger, self.hass, self._send_message, request) connection = None disconnect_warn = None try: self._send_message(auth_required_message()) # Auth Phase try: with async_timeout.timeout(10): msg = await wsock.receive() except asyncio.TimeoutError: disconnect_warn = \ 'Did not receive auth message within 10 seconds' raise Disconnect if msg.type in (WSMsgType.CLOSE, WSMsgType.CLOSING): raise Disconnect elif msg.type != WSMsgType.TEXT: disconnect_warn = 'Received non-Text message.' raise Disconnect try: msg = msg.json() except ValueError: disconnect_warn = 'Received invalid JSON.' raise Disconnect self._logger.debug("Received %s", msg) connection = await auth.async_handle(msg) # Command phase while not wsock.closed: msg = await wsock.receive() if msg.type in (WSMsgType.CLOSE, WSMsgType.CLOSING): break elif msg.type != WSMsgType.TEXT: disconnect_warn = 'Received non-Text message.' break try: msg = msg.json() except ValueError: disconnect_warn = 'Received invalid JSON.' break self._logger.debug("Received %s", msg) connection.async_handle(msg) except asyncio.CancelledError: self._logger.info("Connection closed by client") except Disconnect: pass except Exception: # pylint: disable=broad-except self._logger.exception("Unexpected error inside websocket API") finally: unsub_stop() if connection is not None: connection.async_close() try: self._to_write.put_nowait(None) # Make sure all error messages are written before closing await self._writer_task except asyncio.QueueFull: self._writer_task.cancel() await wsock.close() if disconnect_warn is None: self._logger.debug("Disconnected") else: self._logger.warning("Disconnected: %s", disconnect_warn) return wsock
def current_asyncio_task(loop): return asyncio.current_task(loop)