Exemple #1
0
def launch_node(args: Namespace, chain_config: ChainConfig, endpoint: Endpoint) -> None:
    with chain_config.process_id_file('networking'):

        endpoint.connect()

        NodeClass = chain_config.node_class
        # Temporary hack: We setup a second instance of the PluginManager.
        # The first instance was only to configure the ArgumentParser whereas
        # for now, the second instance that lives inside the networking process
        # performs the bulk of the work. In the future, the PluginManager
        # should probably live in its own process and manage whether plugins
        # run in the shared plugin process or spawn their own.

        plugin_manager = setup_plugins(SharedProcessScope(endpoint))
        plugin_manager.prepare(args, chain_config)
        plugin_manager.broadcast(HeliosStartupEvent(
            args,
            chain_config
        ))

        node = NodeClass(plugin_manager, chain_config)
        loop = node.get_event_loop()
        asyncio.ensure_future(handle_networking_exit(node, plugin_manager, endpoint), loop=loop)
        asyncio.ensure_future(node.run(), loop=loop)
        loop.run_forever()
        loop.close()
Exemple #2
0
def run_database_process(chain_config: ChainConfig, db_class: Type[BaseDB]) -> None:
    with chain_config.process_id_file('database'):

        if chain_config.report_memory_usage:
            from threading import Thread
            memory_logger = logging.getLogger('hvm.memoryLogger')

            t = Thread(target=sync_periodically_report_memory_stats, args=(chain_config.memory_usage_report_interval, memory_logger))
            t.start()


        base_db = db_class(db_path=chain_config.database_dir)

        # TODO:remove
        #base_db = JournalDB(base_db)

        manager = get_chaindb_manager(chain_config, base_db)
        server = manager.get_server()  # type: ignore

        def _sigint_handler(*args: Any) -> None:
            server.stop_event.set()

        signal.signal(signal.SIGINT, _sigint_handler)
        try:
            server.serve_forever()
        except SystemExit:
            server.stop_event.set()
            raise
Exemple #3
0
def run_chain_process(chain_config: ChainConfig, instance = 0) -> None:
    with chain_config.process_id_file('database_{}'.format(instance)):
        # connect with database process
        db_manager = create_db_manager(chain_config.database_ipc_path)
        db_manager.connect()

        base_db = db_manager.get_db()

        # start chain process
        manager = get_chain_manager(chain_config, base_db, instance)
        server = manager.get_server()  # type: ignore

        def _sigint_handler(*args: Any) -> None:
            server.stop_event.set()

        signal.signal(signal.SIGINT, _sigint_handler)
        try:
            server.serve_forever()
        except SystemExit:
            server.stop_event.set()
            raise
Exemple #4
0
def helios_boot(args: Namespace, chain_config: ChainConfig,
                extra_kwargs: Dict[str, Any], plugin_manager: PluginManager,
                listener: logging.handlers.QueueListener, event_bus: EventBus,
                main_endpoint: Endpoint, logger: logging.Logger) -> None:
    # start the listener thread to handle logs produced by other processes in
    # the local logger.
    listener.start()
    logger.info(
        "Checking for any already running Helios Protocol processes that need shutting down. Remember that you can only run 1 instance at a time."
    )
    fix_unclean_shutdown(chain_config, logger)
    with chain_config.process_id_file('main'):
        networking_endpoint = event_bus.create_endpoint(
            NETWORKING_EVENTBUS_ENDPOINT)
        event_bus.start()

        # First initialize the database process.
        database_server_process = ctx.Process(
            target=run_database_process,
            args=(
                chain_config,
                LevelDB,
            ),
            kwargs=extra_kwargs,
        )

        chain_processes = []
        for i in range(chain_config.num_chain_processes):
            chain_process = ctx.Process(
                target=run_chain_process,
                args=(chain_config, i),
                kwargs=extra_kwargs,
            )
            chain_processes.append(chain_process)

        networking_process = ctx.Process(
            target=launch_node,
            args=(
                args,
                chain_config,
                networking_endpoint,
            ),
            kwargs=extra_kwargs,
        )

        # start the processes
        database_server_process.start()
        logger.info("Started DB server process (pid=%d)",
                    database_server_process.pid)

        # networking process needs the IPC socket file provided by the database process
        try:
            wait_for_ipc(chain_config.database_ipc_path)
        except TimeoutError as e:
            logger.error("Timeout waiting for database to start.  Exiting...")
            kill_process_gracefully(database_server_process, logger)
            ArgumentParser().error(
                message="Timed out waiting for database start")

        for i in range(chain_config.num_chain_processes):
            chain_process = chain_processes[i]
            chain_process.start()
            logger.info("Started chain instance {} process (pid={})".format(
                i, chain_process.pid))
            try:
                wait_for_ipc(chain_config.get_chain_ipc_path(i))
            except TimeoutError as e:
                logger.error(
                    "Timeout waiting for chain instance {} to start.  Exiting..."
                    .format(i))
                kill_process_gracefully(chain_process, logger)
                for j in range(i + 1):
                    kill_process_gracefully(chain_processes[j], logger)
                ArgumentParser().error(
                    message="Timed out waiting for chain instance {} start".
                    format(i))

        networking_process.start()
        logger.info("Started networking process (pid=%d)",
                    networking_process.pid)

        main_endpoint.subscribe(
            ShutdownRequest, lambda ev: kill_helios_gracefully(
                logger, database_server_process, chain_processes,
                networking_process, plugin_manager, main_endpoint, event_bus))

        plugin_manager.prepare(args, chain_config, extra_kwargs)
        plugin_manager.broadcast(HeliosStartupEvent(args, chain_config))
        try:
            loop = asyncio.get_event_loop()
            loop.run_forever()
            loop.close()
        except KeyboardInterrupt:
            kill_helios_gracefully(logger, database_server_process,
                                   chain_processes, networking_process,
                                   plugin_manager, main_endpoint, event_bus)