async def test_main_actor_pool(): config = ActorPoolConfig() my_label = 'computation' main_address = f'127.0.0.1:{get_next_port()}' config.add_pool_conf(0, 'main', 'unixsocket:///0', main_address) config.add_pool_conf(1, my_label, 'unixsocket:///1', f'127.0.0.1:{get_next_port()}', env={'my_env': '1'}) config.add_pool_conf(2, my_label, 'unixsocket:///2', f'127.0.0.1:{get_next_port()}') strategy = IdleLabel(my_label, 'my_test') async with await MainActorPool.create({'actor_pool_config': config}) as pool: create_actor_message = CreateActorMessage(new_message_id(), TestActor, b'test', tuple(), dict(), MainPool()) message = await pool.create_actor(create_actor_message) actor_ref = message.result assert actor_ref.address == main_address create_actor_message1 = CreateActorMessage(new_message_id(), TestActor, b'test1', tuple(), dict(), strategy) message1 = await pool.create_actor(create_actor_message1) actor_ref1 = message1.result assert actor_ref1.address in config.get_external_addresses(my_label) create_actor_message2 = CreateActorMessage(new_message_id(), TestActor, b'test2', tuple(), dict(), strategy) message2 = await pool.create_actor(create_actor_message2) actor_ref2 = message2.result assert actor_ref2.address in config.get_external_addresses(my_label) assert actor_ref2.address != actor_ref1.address create_actor_message3 = CreateActorMessage(new_message_id(), TestActor, b'test3', tuple(), dict(), strategy) message3 = await pool.create_actor(create_actor_message3) # no slot to allocate the same label assert isinstance(message3.error, NoIdleSlot) has_actor_message = HasActorMessage( new_message_id(), create_actor_ref(main_address, b'test2')) assert (await pool.has_actor(has_actor_message)).result is True actor_ref_message = ActorRefMessage( new_message_id(), create_actor_ref(main_address, b'test2')) assert (await pool.actor_ref(actor_ref_message)).result == actor_ref2 # tell tell_message = TellMessage(new_message_id(), actor_ref1, ('add', 0, (2, ), dict())) message = await pool.tell(tell_message) assert message.result is None # send send_message = SendMessage(new_message_id(), actor_ref1, ('add', 0, (4, ), dict())) assert (await pool.send(send_message)).result == 6 # test error message # type mismatch send_message = SendMessage(new_message_id(), actor_ref1, ('add', 0, ('3', ), dict())) result = await pool.send(send_message) assert isinstance(result.error, TypeError) # send and tell to main process tell_message = TellMessage(new_message_id(), actor_ref, ('add', 0, (2, ), dict())) message = await pool.tell(tell_message) assert message.result is None send_message = SendMessage(new_message_id(), actor_ref, ('add', 0, (4, ), dict())) assert (await pool.send(send_message)).result == 6 # send and cancel send_message = SendMessage(new_message_id(), actor_ref1, ('sleep', 0, (20, ), dict())) result_task = asyncio.create_task(pool.send(send_message)) start = time.time() cancel_message = CancelMessage(new_message_id(), actor_ref1.address, send_message.message_id) cancel_task = asyncio.create_task(pool.cancel(cancel_message)) result = await asyncio.wait_for(cancel_task, 3) assert result.message_type == MessageType.result assert result.result is True result = await result_task assert time.time() - start < 3 assert result.message_type == MessageType.result assert result.result == 7 # destroy destroy_actor_message = DestroyActorMessage(new_message_id(), actor_ref1) message = await pool.destroy_actor(destroy_actor_message) assert message.result == actor_ref1.uid # destroy via connecting to sub pool directly async with await pool.router.get_client( config.get_external_addresses()[-1]) as client: destroy_actor_message = DestroyActorMessage( new_message_id(), actor_ref2) await client.send(destroy_actor_message) result = await client.recv() assert result.result == actor_ref2.uid # test sync config config.add_pool_conf(3, 'sub', 'unixsocket:///3', f'127.0.0.1:{get_next_port()}') sync_config_message = ControlMessage(new_message_id(), pool.external_address, ControlMessageType.sync_config, config) message = await pool.handle_control_command(sync_config_message) assert message.result is True # test get config get_config_message = ControlMessage(new_message_id(), config.get_external_addresses()[1], ControlMessageType.get_config, None) message = await pool.handle_control_command(get_config_message) config2 = message.result assert config.as_dict() == config2.as_dict() assert pool.stopped
async def test_sub_actor_pool(notify_main_pool): notify_main_pool.return_value = None config = ActorPoolConfig() config.add_pool_conf(0, 'main', 'unixsocket:///0', f'127.0.0.1:{get_next_port()}') config.add_pool_conf(1, 'sub', 'unixsocket:///1', f'127.0.0.1:{get_next_port()}') pool = await SubActorPool.create({ 'actor_pool_config': config, 'process_index': 1 }) await pool.start() create_actor_message = CreateActorMessage( new_message_id(), TestActor, b'test', tuple(), dict(), AddressSpecified(pool.external_address)) message = await pool.create_actor(create_actor_message) assert message.message_type == MessageType.result actor_ref = message.result assert actor_ref.address == pool.external_address assert actor_ref.uid == b'test' has_actor_message = HasActorMessage(new_message_id(), actor_ref) assert (await pool.has_actor(has_actor_message)).result is True actor_ref_message = ActorRefMessage(new_message_id(), actor_ref) assert (await pool.actor_ref(actor_ref_message)).result == actor_ref tell_message = TellMessage(new_message_id(), actor_ref, ('add', 0, (1, ), dict())) message = await pool.tell(tell_message) assert message.result is None send_message = SendMessage(new_message_id(), actor_ref, ('add', 0, (3, ), dict())) message = await pool.send(send_message) assert message.result == 4 # test error message # type mismatch send_message = SendMessage(new_message_id(), actor_ref, ('add', 0, ('3', ), dict())) result = await pool.send(send_message) assert result.message_type == MessageType.error assert isinstance(result.error, TypeError) send_message = SendMessage( new_message_id(), create_actor_ref(actor_ref.address, 'non_exist'), ('add', 0, (3, ), dict())) result = await pool.send(send_message) assert isinstance(result.error, ActorNotExist) # test send message and cancel it send_message = SendMessage(new_message_id(), actor_ref, ('sleep', 0, (20, ), dict())) result_task = asyncio.create_task(pool.send(send_message)) await asyncio.sleep(0) start = time.time() cancel_message = CancelMessage(new_message_id(), actor_ref.address, send_message.message_id) cancel_task = asyncio.create_task(pool.cancel(cancel_message)) result = await asyncio.wait_for(cancel_task, 3) assert result.message_type == MessageType.result assert result.result is True result = await result_task # test time assert time.time() - start < 3 assert result.message_type == MessageType.result assert result.result == 5 # test processing message on background async with await pool.router.get_client(pool.external_address) as client: send_message = SendMessage(new_message_id(), actor_ref, ('add', 0, (5, ), dict())) await client.send(send_message) result = await client.recv() assert result.result == 9 send_message = SendMessage(new_message_id(), actor_ref, ('add', 0, ('5', ), dict())) await client.send(send_message) result = await client.recv() assert isinstance(result.error, TypeError) destroy_actor_message = DestroyActorMessage(new_message_id(), actor_ref) message = await pool.destroy_actor(destroy_actor_message) assert message.result == actor_ref.uid # send destroy failed message = await pool.destroy_actor(destroy_actor_message) assert isinstance(message.error, ActorNotExist) message = await pool.has_actor(has_actor_message) assert not message.result # test sync config config.add_pool_conf(1, 'sub', 'unixsocket:///1', f'127.0.0.1:{get_next_port()}') sync_config_message = ControlMessage(new_message_id(), '', ControlMessageType.sync_config, config) message = await pool.handle_control_command(sync_config_message) assert message.result is True # test get config get_config_message = ControlMessage(new_message_id(), '', ControlMessageType.get_config, None) message = await pool.handle_control_command(get_config_message) config2 = message.result assert config.as_dict() == config2.as_dict() assert pool.router._mapping == Router.get_instance()._mapping assert pool.router._curr_external_addresses == \ Router.get_instance()._curr_external_addresses stop_message = ControlMessage(new_message_id(), '', ControlMessageType.stop, None) message = await pool.handle_control_command(stop_message) assert message.result is True await pool.join(.05) assert pool.stopped
async def test_main_actor_pool(): config = ActorPoolConfig() my_label = 'computation' main_address = f'127.0.0.1:{get_next_port()}' config.add_pool_conf(0, 'main', 'unixsocket:///0', main_address) config.add_pool_conf(1, my_label, 'unixsocket:///1', f'127.0.0.1:{get_next_port()}', env={'my_env': '1'}) config.add_pool_conf(2, my_label, 'unixsocket:///2', f'127.0.0.1:{get_next_port()}') strategy = IdleLabel(my_label, 'my_test') async with await MainActorPool.create({'actor_pool_config': config}) as pool: create_actor_message = CreateActorMessage(new_message_id(), TestActor, b'test', tuple(), dict(), MainPool()) message = await pool.create_actor(create_actor_message) actor_ref = message.result assert actor_ref.address == main_address create_actor_message1 = CreateActorMessage(new_message_id(), TestActor, b'test1', tuple(), dict(), strategy) message1 = await pool.create_actor(create_actor_message1) actor_ref1 = message1.result assert actor_ref1.address in config.get_external_addresses(my_label) create_actor_message2 = CreateActorMessage(new_message_id(), TestActor, b'test2', tuple(), dict(), strategy) message2 = await pool.create_actor(create_actor_message2) actor_ref2 = message2.result assert actor_ref2.address in config.get_external_addresses(my_label) assert actor_ref2.address != actor_ref1.address create_actor_message3 = CreateActorMessage(new_message_id(), TestActor, b'test3', tuple(), dict(), strategy) message3 = await pool.create_actor(create_actor_message3) # no slot to allocate the same label assert isinstance(message3.error, NoIdleSlot) has_actor_message = HasActorMessage( new_message_id(), create_actor_ref(main_address, b'test2')) assert (await pool.has_actor(has_actor_message)).result is True actor_ref_message = ActorRefMessage( new_message_id(), create_actor_ref(main_address, b'test2')) assert (await pool.actor_ref(actor_ref_message)).result == actor_ref2 # tell tell_message = TellMessage(new_message_id(), actor_ref1, ('add', 2, dict())) message = await pool.tell(tell_message) assert message.result is None # send send_message = SendMessage(new_message_id(), actor_ref1, ('add', 4, dict())) assert (await pool.send(send_message)).result == 6 # test error message # type mismatch send_message = SendMessage(new_message_id(), actor_ref1, ('add', '3', dict())) result = await pool.send(send_message) assert isinstance(result.error, TypeError) # send and tell to main process tell_message = TellMessage(new_message_id(), actor_ref, ('add', 2, dict())) message = await pool.tell(tell_message) assert message.result is None send_message = SendMessage(new_message_id(), actor_ref, ('add', 4, dict())) assert (await pool.send(send_message)).result == 6 # destroy destroy_actor_message = DestroyActorMessage(new_message_id(), actor_ref1) message = await pool.destroy_actor(destroy_actor_message) assert message.result == actor_ref1.uid # destroy via connecting to sub pool directly async with await pool.router.get_client( config.get_external_addresses()[-1]) as client: destroy_actor_message = DestroyActorMessage( new_message_id(), actor_ref2) await client.send(destroy_actor_message) result = await client.recv() assert result.result == actor_ref2.uid assert pool.stopped