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
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
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, )
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
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)
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, )
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)
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], )
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, )
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, )