Beispiel #1
0
async def test_sub_service_cancelled_when_parent_stops():
    ready_cancel = trio.Event()

    # This test runs a service that runs a sub-service that sleeps forever. When the parent exits,
    # the sub-service should be cancelled as well.
    @as_service
    async def WaitForeverService(manager):
        ready_cancel.set()
        await manager.wait_finished()

    sub_manager = TrioManager(WaitForeverService())

    @as_service
    async def ServiceTest(manager):
        async def run_sub():
            await sub_manager.run()

        manager.run_task(run_sub)
        await manager.wait_finished()

    s = ServiceTest()
    async with background_trio_service(s) as manager:
        await ready_cancel.wait()

    assert not manager.is_running
    assert manager.is_cancelled
    assert manager.is_finished

    assert not sub_manager.is_running
    assert not sub_manager.is_cancelled
    assert sub_manager.is_finished
Beispiel #2
0
def test_service_manager_initial_state():
    service = WaitCancelledService()
    manager = TrioManager(service)

    assert manager.is_started is False
    assert manager.is_running is False
    assert manager.is_cancelled is False
    assert manager.is_finished is False
Beispiel #3
0
async def test_trio_service_lifecycle_run_and_external_cancellation():
    @as_service
    async def ServiceTest(manager):
        await trio.sleep_forever()

    service = ServiceTest()
    manager = TrioManager(service)

    await do_service_lifecycle_check(
        manager=manager,
        manager_run_fn=manager.run,
        trigger_exit_condition_fn=manager.cancel,
        should_be_cancelled=True,
    )
Beispiel #4
0
async def test_trio_service_manager_propogates_and_records_exceptions():
    @as_service
    async def ThrowErrorService(manager):
        raise RuntimeError("this is the error")

    service = ThrowErrorService()
    manager = TrioManager(service)

    assert manager.did_error is False

    with pytest.raises(RuntimeError, match="this is the error"):
        await manager.run()

    assert manager.did_error is True
Beispiel #5
0
def _boot() -> None:
    try:
        manager = TrioManager(BootService())

        trio.run(manager.run)
    except KeyboardInterrupt:
        import logging
        import sys
        logger = logging.getLogger()
        logger.info('Stopping: Fast CTRL+C')
        sys.exit(2)
    else:
        import sys
        sys.exit(0)
Beispiel #6
0
async def test_trio_service_lifecycle_run_and_clean_exit():
    trigger_exit = trio.Event()

    @as_service
    async def ServiceTest(manager):
        await trigger_exit.wait()

    service = ServiceTest()
    manager = TrioManager(service)

    await do_service_lifecycle_check(
        manager=manager,
        manager_run_fn=manager.run,
        trigger_exit_condition_fn=trigger_exit.set,
        should_be_cancelled=False,
    )
Beispiel #7
0
def _boot() -> None:
    # from cthaeh._profiling import profiler
    try:
        manager = TrioManager(BootService())

        # with profiler('/home/piper/projects/cthaeh/tmp/profile.stats'):
        trio.run(manager.run)
    except KeyboardInterrupt:
        import logging
        import sys

        logger = logging.getLogger()
        logger.info("Stopping: Fast CTRL+C")
        sys.exit(2)
    else:
        import sys

        sys.exit(0)
Beispiel #8
0
    def register_peer_packer(self, remote_node_id: NodeID) -> None:
        if self.is_peer_packer_registered(remote_node_id):
            raise ValueError(
                f"Peer packer for {encode_hex(remote_node_id)} is already registered"
            )

        incoming_packet_channels: Tuple[
            SendChannel[IncomingPacket],
            ReceiveChannel[IncomingPacket], ] = trio.open_memory_channel(0)
        outgoing_message_channels: Tuple[
            SendChannel[OutgoingMessage],
            ReceiveChannel[OutgoingMessage], ] = trio.open_memory_channel(0)

        peer_packer = PeerPacker(
            local_private_key=self.local_private_key,
            local_node_id=self.local_node_id,
            remote_node_id=remote_node_id,
            node_db=self.node_db,
            message_type_registry=self.message_type_registry,
            incoming_packet_receive_channel=incoming_packet_channels[1],
            # These channels are the standard `trio.abc.XXXChannel` interfaces.
            # The `clone` method is only available on `MemoryXXXChannel` types
            # which trio currently doesn't expose in a way that allows us to
            # type these channels as those types.  Thus, we need to tell mypy
            # to ignore this since it doesn't recognize the standard
            # `trio.abc.XXXChannel` interfaces as having a `clone()` method.
            incoming_message_send_channel=self.incoming_message_send_channel.
            clone(),  # type: ignore  # noqa: E501
            outgoing_message_receive_channel=outgoing_message_channels[1],
            outgoing_packet_send_channel=self.outgoing_packet_send_channel.
            clone(),  # type: ignore
        )

        manager = TrioManager(peer_packer)

        self.managed_peer_packers[remote_node_id] = ManagedPeerPacker(
            peer_packer=peer_packer,
            manager=manager,
            incoming_packet_send_channel=incoming_packet_channels[0],
            outgoing_message_send_channel=outgoing_message_channels[0],
        )
Beispiel #9
0
async def test_trio_service_lifecycle_run_and_exception():
    trigger_error = trio.Event()

    @as_service
    async def ServiceTest(manager):
        await trigger_error.wait()
        raise RuntimeError("Service throwing error")

    service = ServiceTest()
    manager = TrioManager(service)

    async def do_service_run():
        with pytest.raises(RuntimeError, match="Service throwing error"):
            await manager.run()

    await do_service_lifecycle_check(
        manager=manager,
        manager_run_fn=do_service_run,
        trigger_exit_condition_fn=trigger_error.set,
        should_be_cancelled=True,
    )
Beispiel #10
0
async def test_trio_service_lifecycle_run_and_daemon_task_exit():
    trigger_error = trio.Event()

    @as_service
    async def ServiceTest(manager):
        async def daemon_task_fn():
            await trigger_error.wait()

        manager.run_daemon_task(daemon_task_fn)
        await manager.wait_finished()

    service = ServiceTest()
    manager = TrioManager(service)

    async def do_service_run():
        with pytest.raises(DaemonTaskExit, match="Daemon task"):
            await manager.run()

    await do_service_lifecycle_check(
        manager=manager,
        manager_run_fn=do_service_run,
        trigger_exit_condition_fn=trigger_error.set,
        should_be_cancelled=True,
    )