def run_forever(self, *, loop=None, consume_rpcs=True, consume_events=True, plugins=None): logger.info(LBullets( "Lightbus getting ready to run. Brokers in use", items={ "RPC transport": L( '{}.{}', self.rpc_transport.__module__, Bold(self.rpc_transport.__class__.__name__) ), "Result transport": L( '{}.{}', self.result_transport.__module__, Bold(self.result_transport.__class__.__name__) ), "Event transport": L( '{}.{}', self.event_transport.__module__, Bold(self.event_transport.__class__.__name__) ), } )) self.setup(plugins=plugins) registry.add(LightbusStateApi()) registry.add(LightbusMetricsApi()) if consume_rpcs: if registry.public(): logger.info(LBullets( "APIs in registry ({})".format(len(registry.all())), items=registry.all() )) else: if consume_events: logger.warning( "No APIs have been registered, lightbus may still receive events " "but Lightbus will not handle any incoming RPCs" ) else: logger.error( "No APIs have been registered, yet Lightbus has been configured to only " "handle RPCs. There is therefore nothing for lightbus to do. Exiting." ) return block(handle_aio_exceptions( plugin_hook('before_server_start', bus_client=self, loop=loop) ), timeout=5) loop = loop or asyncio.get_event_loop() self._run_forever(loop, consume_rpcs, consume_events) loop.run_until_complete(handle_aio_exceptions( plugin_hook('after_server_stopped', bus_client=self, loop=loop) ))
def _run_forever(self, consume_rpcs): # Setup RPC consumption consume_rpc_task = None if consume_rpcs and registry.all(): consume_rpc_task = asyncio.ensure_future(self.consume_rpcs()) # Setup schema monitoring monitor_task = asyncio.ensure_future(self.schema.monitor()) self.loop.add_signal_handler(signal.SIGINT, self.loop.stop) self.loop.add_signal_handler(signal.SIGTERM, self.loop.stop) try: self._actually_run_forever() logger.warning("Interrupt received. Shutting down...") except KeyboardInterrupt: logger.warning("Keyboard interrupt. Shutting down...") # The loop has stopped, so we're shutting down # Remove the signal handlers self.loop.remove_signal_handler(signal.SIGINT) self.loop.remove_signal_handler(signal.SIGTERM) # Cancel the tasks we created above block(cancel(consume_rpc_task, monitor_task), timeout=1)
def _run_forever(self, loop, consume_rpcs, consume_events): if consume_rpcs and registry.all(): asyncio.ensure_future(handle_aio_exceptions(self.consume_rpcs()), loop=loop) if consume_events: asyncio.ensure_future(handle_aio_exceptions(self.consume_events()), loop=loop) try: loop.run_forever() except KeyboardInterrupt: logger.error('Keyboard interrupt. Shutting down...') finally: for task in asyncio.Task.all_tasks(): task.cancel()
def run_forever(self, *, consume_rpcs=True): registry.add(LightbusStateApi()) registry.add(LightbusMetricsApi()) if consume_rpcs: logger.info( LBullets("APIs in registry ({})".format(len(registry.all())), items=registry.names())) block(self._plugin_hook("before_server_start"), timeout=5) self._run_forever(consume_rpcs) self.loop.run_until_complete(self._plugin_hook("after_server_stopped")) # Close the bus (which will in turn close the transports) self.close() # See if we've set the exit code on the event loop if hasattr(self.loop, "lightbus_exit_code"): raise SystemExit(self.loop.lightbus_exit_code)
async def consume_rpcs(self, apis=None): if apis is None: apis = registry.all() while True: rpc_messages = await self.rpc_transport.consume_rpcs(apis) for rpc_message in rpc_messages: await plugin_hook('before_rpc_execution', rpc_message=rpc_message, bus_client=self) try: result = await self.call_rpc_local( api_name=rpc_message.api_name, name=rpc_message.procedure_name, kwargs=rpc_message.kwargs ) except SuddenDeathException: # Used to simulate message failure for testing pass else: result_message = ResultMessage(result=result, rpc_id=rpc_message.rpc_id) await plugin_hook('after_rpc_execution', rpc_message=rpc_message, result_message=result_message, bus_client=self) await self.send_result(rpc_message=rpc_message, result_message=result_message)
async def consume_rpcs(self, apis: List[Api] = None): if apis is None: apis = registry.all() if not apis: raise NoApisToListenOn( "No APIs to consume on in consume_rpcs(). Either this method was called with apis=[], " "or the API registry is empty.") while True: # Not all APIs will necessarily be served by the same transport, so group them # accordingly api_names = [api.meta.name for api in apis] api_names_by_transport = self.transport_registry.get_rpc_transports( api_names) coroutines = [] for rpc_transport, transport_api_names in api_names_by_transport: transport_apis = list(map(registry.get, transport_api_names)) coroutines.append( self._consume_rpcs_with_transport( rpc_transport=rpc_transport, apis=transport_apis)) await asyncio.gather(*coroutines)
async def setup_async(self, plugins: dict = None): """Setup lightbus and get it ready to consume events and/or RPCs You should call this manually if you are calling `consume_rpcs()` directly. This you be handled for you if you are calling `run_forever()`. """ logger.info( LBullets( "Lightbus is setting up", items={ "service_name (set with -s or LIGHTBUS_SERVICE_NAME)": Bold(self.config.service_name), "process_name (with with -p or LIGHTBUS_PROCESS_NAME)": Bold(self.config.process_name), }, )) # Log the transport information rpc_transport = self.transport_registry.get_rpc_transport("default", default=None) result_transport = self.transport_registry.get_result_transport( "default", default=None) event_transport = self.transport_registry.get_event_transport( "default", default=None) log_transport_information(rpc_transport, result_transport, event_transport, self.schema.schema_transport, logger) # Log the plugins we have if plugins is None: logger.debug("Auto-loading any installed Lightbus plugins...") # Force auto-loading as many commands need to do config-less best-effort # plugin loading. But now we have the config loaded so we can # make sure we load the plugins properly. plugins = autoload_plugins(self.config, force=True) else: logger.debug("Loading explicitly specified Lightbus plugins....") manually_set_plugins(plugins) if plugins: logger.info( LBullets("Loaded the following plugins ({})".format( len(plugins)), items=plugins)) else: logger.info("No plugins loaded") # Load schema logger.debug("Loading schema...") await self.schema.load_from_bus() # Share the schema of the registered APIs for api in registry.all(): await self.schema.add_api(api) logger.info( LBullets( "Loaded the following remote schemas ({})".format( len(self.schema.remote_schemas)), items=self.schema.remote_schemas.keys(), )) for transport in self.transport_registry.get_all_transports(): await transport.open()