def test_it(defer, make_actor1): node1 = Node(nid='localhost:20001', enable_remoting=True) defer(node1.stop) actor1_msgs = obs_list() actor1 = make_actor1(node1, Props(MockActor, actor1_msgs)) # node2 = Node(nid='localhost:20002', enable_remoting=True) defer(node2.stop) actor2_msgs = obs_list() node2.spawn(Props(MockActor, actor2_msgs), name='actor2') # send: node1 -> node2: node1.lookup_str('localhost:20002/actor2') << ('msg-with-ref', actor1) # reply: node2 -> node1: actor2_msgs.wait_eq([ ANY ], "should be able to send messages to explicitly constructed remote refs" ) _, received_ref = actor2_msgs[0] received_ref << ('hello', received_ref) actor1_msgs.wait_eq( [('hello', received_ref)], "should be able to send messages to received remote refs") # send to self without knowing it (_, re_received_ref), = actor1_msgs del actor1_msgs[:] re_received_ref << 'to-myself' actor1_msgs.wait_eq(['to-myself'])
def test_incoming_refs_pointing_to_local_actors_are_converted_to_local_refs( defer): # node1: node1 = Node('localhost:20001', enable_remoting=True) defer(node1.stop) actor1_msgs = obs_list() actor1 = node1.spawn(Props(MockActor, actor1_msgs), name='actor1') # node2: node2 = Node('localhost:20002', enable_remoting=True) defer(node2.stop) actor2_msgs = obs_list() node2.spawn(Props(MockActor, actor2_msgs), name='actor2') # send from node1 -> node2: node1.lookup_str('localhost:20002/actor2') << ('msg-with-ref', actor1) # reply from node2 -> node1: _, received_ref = actor2_msgs.wait_eq([ANY])[0] received_ref << ('msg-with-ref', received_ref) (_, remote_local_ref), = actor1_msgs.wait_eq([ANY]) ok_(remote_local_ref.is_local)
def test_sending_operator_is_chainable(defer): # Trivial send and receive using the << operator. messages = obs_list() node = DummyNode() defer(node.stop) a = node.spawn(Props(MockActor, messages)) a << 'foo' << 'bar' messages.wait_eq(['foo', 'bar'])
def test_sent_message_is_received(defer): # Trivial send and receive. messages = obs_list() node = DummyNode() defer(node.stop) a = node.spawn(Props(MockActor, messages)) a << 'foo' messages.wait_eq(['foo'])
def test_sending_to_a_remote_ref_that_points_to_a_local_ref_is_redirected( defer): node = Node('localhost:20000', enable_remoting=True) defer(node.stop) msgs = obs_list() node.spawn(Props(MockActor, msgs), name='localactor') ref = Ref(cell=None, uri=Uri.parse('localhost:20000/localactor'), is_local=False, node=node) ref << 'foo' msgs.wait_eq(['foo']) ok_(ref.is_local) ref << 'bar' msgs.wait_eq(['foo', 'bar'])
def test_sending_remote_refs(defer): """Sending remote refs. The sender acquires a remote ref to an actor on the target and sends it to the sender, who then sends a message. to the target. It forms a triangle where 1) M obtains a reference to T, 2) sends it over to S, and then 3) S uses it to start communication with T. T ---- S \ / \ / M """ target_node = Node('localhost:20003', enable_remoting=True) defer(target_node.stop) target_msgs = obs_list() target_node.spawn(Props(MockActor, target_msgs), name='T') # sender_node = Node('localhost:20001', enable_remoting=True) defer(sender_node.stop) class SenderActor(Actor): def receive(self, msg): eq_(msg, ('send-msg-to', ANY)) _, target = msg target << 'helo' sender_node.spawn(SenderActor, name='S') # middle_node = Node('localhost:20002', enable_remoting=True) defer(middle_node.stop) ref_to_sender = middle_node.lookup_str('localhost:20001/S') ref_to_target = middle_node.lookup_str('localhost:20003/T') ref_to_sender << ('send-msg-to', ref_to_target) target_msgs.wait_eq(['helo'])
def test_actorref_remote_returns_a_ref_that_when_sent_a_message_delivers_it_on_another_node( defer): # This just tests the routing logic and not heartbeat or reliability or deadletters or anything. # emulate a scenario in which a single node sends many messages to other nodes; # a total of NUM_NODES * NUM_ACTORS messages will be sent out. NUM_NODES = 1 NUM_ACTORS_PER_NODE = 2 sender_node = Node(nid='localhost:20000', enable_remoting=True) defer(sender_node.stop) recipient_nodes = [] for node_ix in range(NUM_NODES): nid = 'localhost:2000%d' % (node_ix + 1, ) remote_node = Node(nid=nid, enable_remoting=True) defer(remote_node.stop) receive_boxes = [] sent_msgs = [] for actor_num in range(1, NUM_ACTORS_PER_NODE + 1): actor_box = obs_list() # collects whatever the MockActor receives actor = remote_node.spawn(Props(MockActor, actor_box), name='actor%d' % actor_num) # we only care about the messages received, not the ref itself receive_boxes.append(actor_box) # format: dummy-<nodename>-<actorname>-<random-stuff-for-good-measure> (just for debuggability) msg = 'dummy-%s-%s-%s' % (nid, actor.uri.name, random.randint(1, 10000000)) sender_node.lookup(actor.uri) << msg sent_msgs.append(msg) recipient_nodes.append((sent_msgs, receive_boxes)) for sent_msgs, receive_boxes in recipient_nodes: for sent_msg, receive_box in zip(sent_msgs, receive_boxes): receive_box.wait_eq(terminator=[sent_msg], timeout=None)
def test_sending_to_an_unknown_host_that_becomes_visible_in_time(defer): node1 = Node('localhost:20001', enable_remoting=True, hub_kwargs={ 'heartbeat_interval': 0.05, 'heartbeat_max_silence': 0.5 }) defer(node1.stop) ref = node1.lookup_str('localhost:20002/actor1') with expect_event_not_emitted(DeadLetter): ref << 'foo' sleep(0.1) node2 = Node('localhost:20002', enable_remoting=True) defer(node2.stop) actor2_msgs = obs_list() node2.spawn(Props(MockActor, actor2_msgs), name='actor1') actor2_msgs.wait_eq(['foo'])