Exemple #1
0
    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'])
Exemple #2
0
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)
Exemple #3
0
def test_messages_sent_to_nonexistent_remote_actors_are_deadlettered(defer):
    sender_node, receiver_node = (Node('localhost:20001',
                                       enable_remoting=True),
                                  Node('localhost:20002',
                                       enable_remoting=True))
    defer(sender_node.stop, receiver_node.stop)

    noexist = sender_node.lookup_str('localhost:20002/non-existent-actor')
    with expect_one_event(DeadLetter):
        noexist << 'straight-down-the-drain'
Exemple #4
0
def test_node_gc():
    node1 = Node(nid='localhost:20001', enable_remoting=False)
    ref = weakref.ref(node1)
    node1.stop()
    node1 = None
    gc.collect()
    ok_(not ref())

    node2 = Node(nid='localhost:20002', enable_remoting=True)
    ref = weakref.ref(node2)
    node2.stop()
    node2 = None
    gc.collect()
    ok_(not ref())
Exemple #5
0
def test_looking_up_addresses_that_actually_point_to_the_local_node_return_a_local_ref(
        defer):
    node = Node('localhost:20000', enable_remoting=True)
    defer(node.stop)
    node.spawn(Actor, name='localactor')
    ref = node.lookup_str('localhost:20000/localactor')
    ok_(ref.is_local)
Exemple #6
0
def test_watching_nonexistent_remote_actor_causes_termination_message(defer):
    class Watcher(Actor):
        def pre_start(self):
            self.watch(watchee)

        def receive(self, msg):
            received.set(msg)

    received = AsyncResult()
    node1, node2 = (Node('localhost:20001', enable_remoting=True),
                    Node('localhost:20002', enable_remoting=True))
    defer(node1.stop, node2.stop)

    watchee = node1.lookup_str('localhost:20002/nonexistent-watchee')
    node1.spawn(Watcher)

    eq_(received.get(), ('terminated', watchee))
Exemple #7
0
def test_watching_running_remote_actor_that_stops_causes_termination_message(
        defer):
    class Watcher(Actor):
        def pre_start(self):
            self.watch(
                self.root.node.lookup_str('localhost:20002/remote-watchee'))

        def receive(self, msg):
            received.set(msg)

    received = AsyncResult()
    node1, node2 = Node('localhost:20001',
                        enable_remoting=True), Node('localhost:20002',
                                                    enable_remoting=True)
    defer(node1.stop, node2.stop)

    remote_watchee = node2.spawn(Actor, name='remote-watchee')
    node1.spawn(Watcher)
    remote_watchee.stop()

    eq_(received.get(), ('terminated', remote_watchee))
Exemple #8
0
def test_urlmatch_with_extra_args_to_responder(defer):
    node = Node()
    defer(node.stop)

    responder = make_responder(lambda req, extra: req.write(str(extra)))
    rnd_data = bytes(random.random())
    responders = [(r'', responder.using(extra=rnd_data))]
    http_server = node.spawn(
        HttpServer.using(address=('localhost', 0), responders=responders))
    _, port = actor_exec(node, lambda: http_server.ask('get-addr'))

    eq_(rnd_data, requests.get('http://localhost:%d' % (port, )).text)
Exemple #9
0
def test_sending_to_an_unknown_node_doesnt_start_if_the_node_doesnt_become_visible_and_the_message_is_later_dropped(
        defer):
    sender_node = Node('localhost:20001',
                       enable_remoting=True,
                       hub_kwargs={
                           'heartbeat_interval': 0.05,
                           'heartbeat_max_silence': 0.1
                       })
    defer(sender_node.stop)
    ref = sender_node.lookup_str('localhost:23456/actor2')
    with expect_one_event(DeadLetter(ref, 'bar', sender=None)):
        ref << 'bar'
Exemple #10
0
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'])
Exemple #11
0
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)
Exemple #12
0
    def node(self, nodeid):
        """Creates a new node with the specified name, with `MockSocket` instances as incoming and outgoing sockets.

        Returns the implementation object created for the node from the cls, args and address specified, and the sockets.
        `cls` must be a callable that takes the insock and outsock, and the specified args and kwargs.

        """
        _assert_valid_nodeid(nodeid)
        # addr = 'tcp://' + nodeid
        # insock = MockInSocket(addEndpoints=lambda endpoints: self.bind(addr, insock, endpoints))
        # outsock = lambda: MockOutSocket(addr, self)

        return Node(hub=Hub(nodeid=nodeid))
Exemple #13
0
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'])
Exemple #14
0
def test_stop(defer):
    node = Node()
    defer(node.stop)

    responders = []
    http_server = node.spawn(
        HttpServer.using(address=('localhost', 0), responders=responders))
    _, port = actor_exec(node, lambda: http_server.ask('get-addr'))

    eq_(404, requests.get('http://localhost:%d' % (port, )).status_code)

    http_server.stop()

    with assert_raises(requests.ConnectionError):
        requests.get('http://localhost:%d' % (port, ))
Exemple #15
0
def test_basic(defer):
    node = Node()
    defer(node.stop)

    responders = []
    http_server = node.spawn(
        HttpServer.using(address=('localhost', 0), responders=responders))
    _, port = actor_exec(node, lambda: http_server.ask('get-addr'))

    eq_(404, requests.get('http://localhost:%d' % (port, )).status_code)

    rnd_response = str(random.random())
    responders[:] = [
        (r'^/$', make_responder(lambda request: request.write(rnd_response))),
    ]
    eq_(200, requests.get('http://localhost:%d' % (port, )).status_code)
Exemple #16
0
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'])
Exemple #17
0
def test_file_upload(defer):
    node = Node()
    defer(node.stop)

    def handle_file(request):
        request.write(request.files['file'].read())

    responders = [(r'^/handle-file$', make_responder(handle_file))]
    http_server = node.spawn(
        HttpServer.using(address=('localhost', 0), responders=responders))
    _, port = actor_exec(node, lambda: http_server.ask('get-addr'))

    rnd_data = bytes(random.random())
    with tempfile.NamedTemporaryFile() as f:
        f.write(rnd_data)
        f.flush()
        req = requests.post('http://localhost:%d/handle-file' % (port, ),
                            files={'file': open(f.name, 'rb')})
    eq_(200, req.status_code)
    eq_(rnd_data, req.text)
Exemple #18
0
        def start_actor():
            # if self._nodeid:
            #     log("Setting up remoting; node ID = %s" % (self._nodeid,))
            # else:
            #     log("No remoting requested; specify `--remoting/-r <nodeid>` (nodeid=host:port) to set up remoting")

            self.node = Node(nid=self._nodeid,
                             enable_remoting=True if self._nodeid else False,
                             enable_relay=self._enable_relay)

            try:
                self._wrapper = self.node.spawn(Wrapper.using(
                    self._actor_cls.using(**self._init_params),
                    spawn_at=self._name,
                    keep_running=self._keep_running),
                                                name='_runner')
            except Exception:
                panic("Failed to start wrapper for %s\n" % (actor_path, ),
                      Failure().getTraceback())
                reactor.stop()
            else:
                if self._initial_message is not _EMPTY:
                    self._wrapper << ('_forward', self._initial_message)
Exemple #19
0
def spin(actor_cls,
         name=None,
         init_params={},
         node_id=None,
         initial_messages=[],
         keep_running=False,
         enable_relay=False,
         wrapper_cls=Wrapper):
    node = Node(nid=node_id,
                enable_remoting=True if node_id else False,
                enable_relay=enable_relay)
    stop_event = Event()
    node.spawn(wrapper_cls.using(actor_cls.using(**init_params),
                                 spawn_at=name,
                                 keep_running=keep_running,
                                 initial_messages=initial_messages,
                                 stop_event=stop_event),
               name='-runner')
    try:
        stop_event.wait()
    except KeyboardInterrupt:
        pass
    finally:
        node.stop()
Exemple #20
0
def DummyNode():
    return Node()