Exemplo n.º 1
0
    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)
        ))
Exemplo n.º 2
0
    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)
Exemplo n.º 3
0
    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()
Exemplo n.º 4
0
    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)
Exemplo n.º 5
0
    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)
Exemplo n.º 6
0
    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)
Exemplo n.º 7
0
    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()