def main() -> None: parser = argparse.ArgumentParser() parser.add_argument( "-d", "--debug", help="Set logging level to debug.", action="store_const", const=LogLevel.DEBUG, default=LogLevel.DEBUG if env.get_bool("ARCOR2_LOGGER_DEBUG") else LogLevel.INFO, ) parser.add_argument("--version", action="version", version=version(), help="Shows version and exits.") parser.add_argument( "-a", "--asyncio_debug", help="Turn on asyncio debug mode.", action="store_const", const=True, default=env.get_bool("ARCOR2_LOGGER_ASYNCIO_DEBUG"), ) args = parser.parse_args() logger.level = args.debug run(aio_main(), stop_on_unhandled_errors=True)
def test_sigterm_enduring_indirect_cancel(): items = [] async def corofn(sleep): await asyncio.sleep(sleep) # These next lines can't be hit, because of the cancellation. items.append(True) # pragma: no cover return True # pragma: no cover def direct_cancel(): """Reach inside, find the one task that is marked "do not cancel" for shutdown, and then cancel it directly. This should raise CancelledError at the location of the caller for `shutdown_waits_for()`.""" tasks = all_tasks() for t in tasks: # pragma: no cover if t._coro in _DO_NOT_CANCEL_COROS: t.cancel() return async def main(): loop = asyncio.get_event_loop() coro = corofn(sleep=0.2) loop.call_later(0.1, direct_cancel) with pytest.raises(asyncio.CancelledError): await shutdown_waits_for(coro) kill(SIGTERM, after=0.3) run(main()) assert len(items) == 0
def main(*, config_path: str = DEFAULT_CONFIG_PATH) -> None: """Main entry point for the default bot launcher.""" log.info("Loading config") config_data = Path(config_path).read_text() config: util.config.Config = tomlkit.loads(config_data) # Initialize Sentry reporting here to exempt config syntax errors and query # the user's report_errors value, defaulting to enabled if not specified if config["bot"].get("report_errors", True): log.info("Initializing Sentry error reporting") util.sentry.init() # Use preliminary loop for config upgrading loop = asyncio.get_event_loop() aiorun.run(_upgrade(config, config_path), stop_on_unhandled_errors=True, loop=loop) loop.close() loop = setup_asyncio(config) # Start bot log.info("Initializing bot") aiorun.run(Bot.create_and_run(config, loop=loop), loop=loop)
def test_uvloop(): """Basic SIGTERM""" async def main(): await asyncio.sleep(0) asyncio.get_event_loop().stop() run(main(), use_uvloop=True)
def main_sigterm_enduring_indirect_cancel(q: mp.Queue): async def corofn(): q.put_nowait("ok") await asyncio.sleep(0.2) q.put_nowait(True) def direct_cancel(): """Reach inside, find the one task that is marked "do not cancel" for shutdown, and then cancel it directly. This should raise CancelledError at the location of the caller for `shutdown_waits_for()`.""" tasks = all_tasks() for t in tasks: # pragma: no cover if t._coro in _DO_NOT_CANCEL_COROS: t.cancel() return async def main(): loop = asyncio.get_event_loop() coro = corofn() loop.call_later(0.1, direct_cancel) try: await shutdown_waits_for(coro) except asyncio.CancelledError: q.put_nowait("got cancellation as expected") else: q.put_nowait("no cancellation raised") run(main()) q.put(None) q.join()
def main_shutdown_callback_error_and_main_error(q: mp.Queue): import logging log_messages = [] def filt(record): log_messages.append(record.getMessage()) return record logging.getLogger("aiorun").addFilter(filt) async def main(): await asyncio.sleep(1e-3) raise Exception("main") def shutdown_callback(loop): raise Exception("blah") try: run(main(), stop_on_unhandled_errors=True, shutdown_callback=shutdown_callback) except Exception as e: q.put_nowait(e) else: q.put_nowait("exception was not raised") finally: q.put_nowait(log_messages) q.put_nowait(None) q.join()
def main_shutdown_callback(q: mp.Queue, *, cbtype: "ShutdownCallback"): async def main(): # Inform the test caller that the main coro is ready q.put_nowait("ok") await asyncio.sleep(10.0) # Inform the test caller that the fut was unblocked successfully. q.put_nowait(True) if cbtype is CallbackType.FUNCTION: def shutdown_callback(loop): q.put_nowait(True) elif cbtype is CallbackType.ASYNC_DEF_FUNCTION: async def shutdown_callback(loop): q.put_nowait(True) elif cbtype is CallbackType.COROUTINE_OBJECT: async def shutdown_callback_fn(loop): q.put_nowait(True) shutdown_callback = shutdown_callback_fn(None) else: raise TypeError('Unexpected cbtype') run(main(), shutdown_callback=shutdown_callback) q.put(None) q.join()
def test_sigterm_enduring_await(): """Call `shutdown_waits_for() with await.""" items = [] async def corofn(sleep): """This is the cf that must not be cancelled.""" await asyncio.sleep(sleep) items.append(True) return True async def main(): try: # This one is fast enough to finish out = await shutdown_waits_for(corofn(sleep=0.01)) assert out is True # This one is going to last longer than the shutdown # but we can't get anything back out if that happens. await shutdown_waits_for(corofn(sleep=0.03)) # main() gets cancelled here await asyncio.sleep(2) # pragma: no cover. # This append won't happen items.append(True) # pragma: no cover. except asyncio.CancelledError: print("main got cancelled") raise kill(SIGTERM, after=0.02) run(main()) assert len(items) == 2
def main() -> None: assert sys.version_info >= (3, 8) parser = argparse.ArgumentParser() parser.add_argument("-v", "--verbose", help="Increase verbosity.", action="store_const", const=True, default=False) parser.add_argument( "-d", "--debug", help="Set logging level to debug.", action="store_const", const=LogLevel.DEBUG, default=LogLevel.INFO, ) parser.add_argument("--version", action="version", version=arcor2_arserver.version(), help="Shows version and exits.") parser.add_argument("--api_version", action="version", version=arcor2_arserver_data.version(), help="Shows API version and exits.") parser.add_argument("-a", "--asyncio_debug", help="Turn on asyncio debug mode.", action="store_const", const=True, default=False) parser.add_argument("--openapi", action="store_true", help="Prints OpenAPI models and exits.") args = parser.parse_args() if args.openapi: print_openapi_models() return glob.logger.level = args.debug glob.VERBOSE = args.verbose loop = asyncio.get_event_loop() loop.set_debug(enabled=args.asyncio_debug) compile_json_schemas() if os.path.exists(settings.URDF_PATH): shutil.rmtree(settings.URDF_PATH) os.makedirs(settings.URDF_PATH) run(aio_main(), loop=loop, stop_on_unhandled_errors=True) shutil.rmtree(settings.OBJECT_TYPE_PATH)
def main(): """Main entry point""" log = logging.getLogger("Main") setup_log() log.info("Loading code...") uvloop.install() loop = asyncio.new_event_loop() aiorun.run(anjani.begin(loop=loop), loop=loop)
def test_mutex_exc_handler_and_stop_unhandled(): async def main(): pass loop = newloop() loop.set_exception_handler(lambda loop, ctx: None) with pytest.raises(Exception, match="parameter is unavailable"): run(main(), loop=loop, stop_on_unhandled_errors=True)
def test_sigterm(): """Basic SIGTERM""" async def main(): await asyncio.sleep(5.0) kill(SIGTERM) loop = newloop() run(main(), loop=loop) assert not loop.is_closed()
def main(provider, event_loop): print("Initializing subprocess...", file=sys.stderr) module, variable = provider.split(":") mod = importlib.import_module(module) sp = getattr(mod, variable)() print("Spinning up event-loop", file=sys.stderr) install_event_loop(event_loop) loop = asyncio.get_event_loop() aiorun.run(_run_with_provider(sp), loop=loop) print("Exiting...", file=sys.stderr)
def main(): config = Config.from_environ() configure_logging(config) logger.info(f'Starting Discord Fate Bot {dfb_version}...') async def _main(): database = await get_database(config) bot = DiscordFateBot(config, database) await bot.run() aiorun.run(_main(), stop_on_unhandled_errors=True)
def main_sig_pause(q: mp.Queue): async def main(): try: q.put_nowait("ok") await asyncio.sleep(5.0) except asyncio.CancelledError: print("in cancellation handler") await asyncio.sleep(0.1) run(main()) q.put("done") q.put(None) q.join()
def test_sigterm_enduring_ensure_future(): """Calling `shutdown_waits_for()` via `ensure_future()`""" items = [] async def corofn(): await asyncio.sleep(0.02) items.append(True) async def main(): # Note that we don't need a loop variable anywhere! asyncio.ensure_future(shutdown_waits_for(corofn())) kill(SIGTERM, after=0.01) run(main()) assert items
def test_sigterm_enduring_create_task(): """Calling `shutdown_waits_for()` via `create_task()`""" items = [] async def corofn(): await asyncio.sleep(0.04) items.append(True) async def main(): loop = asyncio.get_event_loop() loop.create_task(shutdown_waits_for(corofn())) kill(SIGTERM, after=0.02) run(main()) assert items
def main_shutdown_callback_error(q: mp.Queue): async def main(): await asyncio.sleep(1e-3) def shutdown_callback(loop): raise Exception("blah") try: run(main(), shutdown_callback=shutdown_callback) except Exception as e: q.put_nowait(e) else: q.put_nowait("exception was not raised") finally: q.put_nowait(None) q.join()
def main(): assert sys.version_info >= (3, 8) parser = argparse.ArgumentParser() parser.add_argument("-v", "--verbose", help="Increase verbosity.", action="store_const", const=True, default=False) parser.add_argument("-d", "--debug", help="Set logging level to debug.", action="store_const", const=LogLevel.DEBUG, default=LogLevel.INFO) parser.add_argument('--version', action='version', version=arcor2.version(), help="Shows ARCOR2 version and exits.") parser.add_argument('--api_version', action='version', version=arcor2.api_version(), help="Shows API version and exits.") parser.add_argument("-a", "--asyncio_debug", help="Turn on asyncio debug mode.", action="store_const", const=True, default=False) args = parser.parse_args() glob.logger.level = args.debug glob.VERBOSE = args.verbose loop = asyncio.get_event_loop() loop.set_debug(enabled=args.asyncio_debug) compile_json_schemas() if os.path.exists(settings.URDF_PATH): shutil.rmtree(settings.URDF_PATH) os.makedirs(settings.URDF_PATH) run(aio_main(), loop=loop, stop_on_unhandled_errors=True)
def main() -> None: """Main entry point for the default bot launcher.""" if sys.platform == "win32": policy = asyncio.WindowsProactorEventLoopPolicy() asyncio.set_event_loop_policy(policy) else: try: import uvloop except ImportError: pass else: uvloop.install() log.info("Using uvloop event loop") log.info("Initializing bot") loop = asyncio.new_event_loop() aiorun.run(Bot.create_and_run(loop=loop), loop=loop)
def aiomain(coro, *args, **kwargs): aiorun.logger.setLevel(51) async def main(): try: await coro(*args, **kwargs) finally: asyncio.get_event_loop().stop() return aiorun.run(main())
def main(q: mp.Queue, **kwargs): async def main(): q.put("ok") await asyncio.sleep(5.0) if kwargs.pop("use_exe", None): exe = ThreadPoolExecutor() else: exe = None loop = None if kwargs.pop("user_supplied_loop", None) and not kwargs.get("use_uvloop"): loop = newloop() try: run(main(), executor=exe, loop=loop, **kwargs) finally: q.put(None) q.join()
def main_shutdown_callback(q: mp.Queue): fut = None async def _main(): nonlocal fut q.put_nowait("ok") fut = asyncio.Future() await fut q.put_nowait(True) async def main(): await shutdown_waits_for(_main()) def shutdown_callback(loop): fut.set_result(None) run(main(), shutdown_callback=shutdown_callback) q.put(None) q.join()
def start(): """Main entry point""" setup_log() log.info("Loading code...") try: import uvloop # pylint: disable=C0415 except ImportError: log.warning("uvloop not installed! Skipping...") print( "\nuvloop not installed! " "bot will work the same, but in a bit slower speed.\n" 'You may install it by "poetry install -E uvloop" or "pip install uvloop"\n' ) else: uvloop.install() loop = asyncio.new_event_loop() aiorun.run(anjani.begin(loop=loop), loop=loop)
def test_sigterm_enduring_bare(): """Call `shutdown_waits_for() without await, or create_task(), or ensure_future(). It's just bare. This actually works (because of the hidden Task inside). However, there will be a RuntimeWarning that the coroutine returned from `shutdown_waits_for() was never awaited. Therefore, maybe best not to use this, just to avoid confusion.""" items = [] async def corofn(): await asyncio.sleep(0.02) items.append(True) async def main(): shutdown_waits_for(corofn()) # <-- Look Ma! No awaits! kill(SIGTERM, after=0.01) run(main()) assert items
def main(*, config_path: str = DEFAULT_CONFIG_PATH) -> None: log.info("Loading config") config_data = Path(config_path).read_text() config: util.config.Config = tomlkit.loads(config_data) # Initialize Sentry reporting here to exempt config syntax errors and query # the user's report_errors value, defaulting to enabled if not specified if config["bot"].get("report_errors", True): log.info("Initializing Sentry error reporting") util.sentry.init() # Use preliminary loop for config upgrading aiorun.run(_upgrade(config, config_path), stop_on_unhandled_errors=True) # Now that the config has been upgraded, we can construct the actual loop loop = setup_asyncio(config) # Start bot with new loop log.info("Initializing bot") aiorun.run(Bot.create_and_run(config), loop=loop)
def main_sigterm_enduring_create_task(q: mp.Queue, spawn_method): async def corofn(): q.put_nowait("ok") await asyncio.sleep(0.05) q.put_nowait(True) async def main(): loop = asyncio.get_event_loop() if spawn_method == "create_task": loop.create_task(shutdown_waits_for(corofn())) elif spawn_method == "ensure_future": asyncio.ensure_future(shutdown_waits_for(corofn())) elif spawn_method == "await": await shutdown_waits_for(corofn()) elif spawn_method == "bare": shutdown_waits_for(corofn()) run(main()) q.put(None) q.join()
def test_sigint_pause(): """Trying to send multiple signals.""" items = [] async def main(): try: await asyncio.sleep(5.0) except asyncio.CancelledError: await asyncio.sleep(0.04) items.append(True) # The first sigint triggers shutdown mode, so all tasks are cancelled. # Note that main() catches CancelledError, and does a little bit more # work before exiting. kill(SIGINT, after=0.02) # The second sigint should have no effect, because aiorun signal # handler disables itself after the first sigint received, above. kill(SIGINT, after=0.03) run(main()) assert items # Verify that main() ran till completion.
def test_exc_stop(): """Basic SIGTERM""" created_tasks = [] async def background_task(): await asyncio.sleep(10) async def main(): # loop = asyncio.get_running_loop() loop = asyncio.get_event_loop() created_tasks.extend(loop.create_task(background_task()) for i in range(10)) await asyncio.sleep(0.01) raise Exception("Stops the loop") with pytest.raises(Exception) as excinfo: run(main(), stop_on_unhandled_errors=True) print(excinfo.traceback) assert "Stops the loop" in str(excinfo.value) assert all(t.cancelled for t in created_tasks)