def exit_from_event_loop_thread(loop: asyncio.AbstractEventLoop, stop: "asyncio.Future[None]") -> None: loop.stop() if not stop.done(): # When exiting the thread that runs the event loop, raise # KeyboardInterrupt in the main thread to exit the program. os.kill(os.getpid(), signal.SIGINT)
async def get_azAlt(dev_uuid: str, loop: asyncio.AbstractEventLoop): async with BleakClient(dev_uuid, loop=loop) as client: # Ensure connection is established await client.is_connected() print("Client Connected!") # Enable notification and assign handler await client.start_notify(azalt_uuid, notification_handler) # Wait for notifications while True: # Await user input x = await aioconsole.ainput(">>> ") x = x.lower() if x == 'c' or x == "calibrate": await calibrate() if x == 't' or x == "temperature": tmp = await client.read_gatt_char(thd_uuid) getTHD(tmp) if x == 'g' or x == "get az/alt": selection = await aioconsole.ainput( "Radians or Degrees (R/D)?: ") if selection == 'R' or selection == 'r': getAzAltRad() else: getAzAltDeg() if x == 'q' or x == 'quit': loop.stop() break
def handle_exception(loop: asyncio.AbstractEventLoop, context: Dict[str, Any]) -> None: nonlocal tb loop.stop() tb = context['message'] exc = context.get('exception') if exc is not None: import traceback tb += '\n' + ''.join(traceback.format_exception(exc.__class__, exc, exc.__traceback__))
async def shutdown(loop: asyncio.AbstractEventLoop): 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) loop.stop()
def custom_exception_handler(loop: asyncio.AbstractEventLoop, context: dict[str, Any]) -> None: # it is also possible to use aiorun.run with stop_on_unhandled_errors=True but this prints much more useful info loop.default_exception_handler(context) if __debug__: # stop loop while debugging, try to continue in production loop.stop()
async def shutdown(loop: asyncio.AbstractEventLoop): print("Nacking outstanding tasks") tasks = [ t for t in asyncio.all_tasks() if t is not asyncio.current_task(loop) ] [task.cancel() for task in tasks] print(f"Cancelling {len(tasks)} outstanding tasks") if (len(tasks)): await asyncio.gather(*tasks) loop.stop()
def loop_exception_handler(loop: asyncio.AbstractEventLoop, context: Dict[str, Any]) -> None: """A custom error handler for the loop, which stops the loop before continuing to the default handler """ logging.error("Terminating loop due to error") if loop.is_running(): loop.stop() loop.default_exception_handler(context)
async def shutdown(signal: signal.Signals, app_registry: AppRegistry, loop: asyncio.AbstractEventLoop) -> None: """Cleanup tasks tied to the service's shutdown.""" logger.info(f'Received exit signal {signal.name}...') logger.info("=========Shutdown=========") await app_registry.shutdown(signal) logger.info('Try to stop event loop') loop.stop()
async def cancel_all_tasks(loop: asyncio.AbstractEventLoop) -> None: tasks = asyncio.Task.all_tasks(loop) this_task = asyncio.Task.current_task(loop) tasks = [] for task in all_tasks: if task != this_task: tasks.append(task) task.cancel() results = await asyncio.gather(*tasks, return_exceptions=True) # NOQA: F841 loop.stop()
def exit_from_event_loop_thread(loop: asyncio.AbstractEventLoop, stop: "asyncio.Future[None]") -> None: loop.stop() if not stop.done(): # When exiting the thread that runs the event loop, raise # KeyboardInterrupt in the main thread to exit the program. if sys.platform == "win32": ctrl_c = signal.CTRL_C_EVENT else: ctrl_c = signal.SIGINT os.kill(os.getpid(), ctrl_c)
def exit_from_event_loop_thread(loop: asyncio.AbstractEventLoop, stop: "asyncio.Future[None]") -> None: loop.stop() if not stop.done(): # When exiting the thread that runs the event loop, raise # KeyboardInterrupt in the main thread to exit the program. try: ctrl_c = signal.CTRL_C_EVENT # Windows except AttributeError: ctrl_c = signal.SIGINT # POSIX os.kill(os.getpid(), ctrl_c)
async def exit_signal(loop: asyncio.AbstractEventLoop) -> AsyncGenerator[None, None]: sigint_received = asyncio.Event() for sig in [signal.SIGINT, signal.SIGTERM]: # TODO also support Windows loop.add_signal_handler(sig, sigint_received.set) await sigint_received.wait() try: yield finally: loop.stop()
def shutdown_loop(loop: asyncio.AbstractEventLoop) -> None: if loop.is_closed(): return try: loop.stop() cancel_all_tasks(loop) loop.run_until_complete(loop.shutdown_asyncgens()) finally: loop.close()
async def shutdown(signal: int, loop: AbstractEventLoop): """Function for graceful shutdown""" print(f"Shutting down.., received signal:{signal}") # collecting tasks tasks = [task for task in asyncio.all_tasks() if task != asyncio.current_task()] # cancelling tasks [task.cancel() for task in tasks] print(f"cancelling {len(tasks)} pending tasks..") # waiting for cancel activity to close. await asyncio.gather(*tasks, return_exceptions=True) # if return_exception is not set it will be handled by # global exception handler loop.stop()
async def async_iterator(application: Gtk.Application, loop: asyncio.AbstractEventLoop) -> None: while Gtk.events_pending(): Gtk.main_iteration_do(False) await asyncio.sleep(0.01) if application.main_window and application.main_window.get_realized(): loop.create_task(async_iterator(application, loop)) else: application.quit() 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 shutdown(loop: AbstractEventLoop, sig: Optional[Signals] = None): """Cleanup tasks tied to the service's shutdown.""" if sig: await logger.info(f"Received exit signal {sig.name}...") tasks = [t for t in asyncio.all_tasks() if t is not asyncio.current_task()] for task in tasks: task.cancel() await logger.info(f"Cancelling {len(tasks)} outstanding tasks") await asyncio.gather(*tasks, return_exceptions=True) loop.stop()
def shutdown_loop(loop: asyncio.AbstractEventLoop) -> None: if loop.is_closed(): return try: loop.stop() cancel_all_tasks(loop) loop.run_until_complete(loop.shutdown_asyncgens()) except RuntimeError as error: log.warning("Error while shutting loop down: %s", str(error)) finally: loop.close()
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()
def test_with_message( self, event_loop: asyncio.AbstractEventLoop, log_records: LogRecordsType, patched_shutdown: AsyncMockType, ) -> None: context = {"message": "exception message"} handle_exception(event_loop, context) event_loop.stop() event_loop.run_forever() expected_record = [ rec for rec in log_records() if rec.levelno == logging.ERROR and "exception message" in rec.message ] assert len(expected_record) assert patched_shutdown.called
def graceful_shutdown(loop: asyncio.AbstractEventLoop = None): tasks = asyncio.gather(*asyncio.Task.all_tasks(loop=loop), loop=loop, return_exceptions=True) tasks.add_done_callback(lambda t: loop.stop()) tasks.cancel() while not tasks.done() and not loop.is_closed(): loop.run_forever() tasks.exception()
def test_with_exc_and_future( self, event_loop: asyncio.AbstractEventLoop, log_records: LogRecordsType, patched_shutdown: AsyncMockType, ) -> None: context = { "exception": ExceptionForTesting("Exception handler test"), "future": asyncio.Future(), } handle_exception(event_loop, context) event_loop.stop() event_loop.run_forever() expected_record = [ rec for rec in log_records() if rec.levelno == logging.ERROR and "ExceptionForTesting" in rec.message and "unknown" in rec.message and "Exception handler test" in rec.message ] assert len(expected_record) assert patched_shutdown.called
def run_debug_commands( commands_file: str, loop: asyncio.AbstractEventLoop, ) -> None: """ Read and execute commands a list of semicolon separated commands as input :param commands: list of semicolon separated commands """ with open(commands_file) as f: commands = f.read().replace('\n', '') commandlist = commands.split(';') for command in commandlist: args = command.split(' ') logger.info("Ran Command %s", args) execute_function(args[0], args[1:], loop) loop.stop()
def console_interface_function(client: MPDClient, loop: asyncio.AbstractEventLoop): """ Simple BLOCKING function with an infinite loop inside that read commands from stdin and pass them to the specified instance of MPDClient :param client: an instance of MPDClient :param loop: target EventLoop :return: None """ while True: data = input() # get another command from user print("Hey!!!", loop, client) # notify user that the command was read, for debugging if data == "exit": # exit from infinite loop on command == "exit" print("Input loop interrupted") break loop.call_soon_threadsafe(pass_command_to_loop, data, client, loop) loop.stop() # Stop event loop and exit from the program
async def shutdown(signal_: signal.Signals, loop_: asyncio.AbstractEventLoop) -> None: """ shutdown coroutine utilized for cleanup on receipt of certain signals. Created and added as a handler to the loop in __main__ https://www.roguelynn.com/talks/ """ log.warning(f'Received exit signal {signal_.name}') tasks: List[asyncio.Task] = [ t for t in asyncio.all_tasks() if t is not asyncio.current_task() ] log.info(f'Cancelling {len(tasks)} outstanding tasks') for task in tasks: task.cancel() await asyncio.gather(*tasks, return_exceptions=True) loop_.stop()
async def shutdown(loop: AbstractEventLoop, signal: Optional[Signals] = None) -> None: logger.debug(f"{type(loop)=}") if signal is not None: logger.info(f"received {signal.name}") logger.info("shutting down...") # Cancel all tasks except itself tasks: List[Task] = [ task for task in asyncio.all_tasks() if task is not asyncio.current_task() ] logger.info(f"cancelling {len(tasks)} tasks...") for t in tasks: t.cancel() await asyncio.gather(*tasks, return_exceptions=True) # Then, stop the loop logger.info("stopping the event loop...") loop.stop()
async def __start_autotrader(auto_trader: BaseAutoTrader, config: Dict[str, Any], loop: asyncio.AbstractEventLoop) -> None: """Initialise an auto-trader.""" logger = logging.getLogger("INIT") info = config["Information"] await create_datagram_endpoint(loop, lambda: auto_trader, (info["ListenAddress"], info["Port"]), family=socket.AF_INET, interface=info["Interface"]) exec_ = config["Execution"] try: await loop.create_connection(lambda: auto_trader, exec_["Host"], exec_["Port"]) except OSError as e: logger.error("execution connection failed: %s", e.strerror) loop.stop() return
def test_with_exc_and_task( self, event_loop: asyncio.AbstractEventLoop, log_records: LogRecordsType, mocker: MockerFixture, patched_shutdown: AsyncMockType, ) -> None: context = { "exception": ExceptionForTesting("Exception handler test"), "future": mocker.Mock(**{"get_name.return_value": "test_task"}), } handle_exception(event_loop, context) event_loop.stop() event_loop.run_forever() expected_record = [ rec for rec in log_records() if rec.levelno == logging.ERROR and "ExceptionForTesting" in rec.message and "test_task" in rec.message and "Exception handler test" in rec.message ] assert len(expected_record) assert patched_shutdown.called
async def shutdown(loop: asyncio.AbstractEventLoop, sig: t.Optional[signal.Signals] = None) -> t.Coroutine: if isinstance(sig, signal.Signals): logging.info("Received exit signal %s...", sig.name) logging.info("Nacking outstanding messages") tasks_to_cancel: t.List[asyncio.Task] = [] for task in asyncio.all_tasks(): if task is not asyncio.current_task(): tasks_to_cancel.append(task) for task in tasks_to_cancel: task.cancel() logging.info("Cancelling %i oustanding tasks" % len(tasks_to_cancel)) await asyncio.gather(*tasks_to_cancel, return_exceptions=True) logging.info("Stopping event loop") loop.stop()
async def run(self, loop: asyncio.AbstractEventLoop) -> None: """ Start the processing. This starts watching for incoming candidates. """ self._running = True self._paused = False logger.info("Starting up processing...") watcher = loop.create_task(self._watch_module.watch(self._candidate_queue)) computer = loop.create_task(self._process(self._candidate_queue)) finaliser = loop.create_task(self._finalise(self._final_queue)) listener = loop.create_task(asyncio.start_server(self._listen, "127.0.0.1", 9999)) await asyncio.gather(listener, watcher, computer, finaliser) logger.info("Finishing the processing...") loop.stop()