Exemple #1
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 #2
0
        def start_actor():
            if self._nodeid:
                Events.log(Message("Setting up remoting; node ID = %s" % (self._nodeid,)))
                try:
                    f1 = ZmqFactory()
                    insock = ZmqPullConnection(f1)
                    outsock = lambda: ZmqPushConnection(f1, linger=0)
                    hub = Hub(insock, outsock, nodeid=self._nodeid)
                except Exception:
                    err("Could not set up remoting")
                    traceback.print_exc()
                    reactor.stop()
                    return
            else:
                Events.log(Message("No remoting requested; specify `--remoting/-r <nodeid>` (nodeid=host:port) to set up remoting"))
                hub = HubWithNoRemoting()

            supervision = {'stop': Stop, 'restart': Restart, 'resume': Resume}[self._supervise]
            node = Node(hub=hub, root_supervision=supervision)

            try:
                self._wrapper = 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 #3
0
class ActorRunner(Service):
    def __init__(
        self,
        actor_cls,
        init_params={},
        initial_message=_EMPTY,
        nodeid=None,
        enable_relay=False,
        name=None,
        keep_running=False,
    ):
        if nodeid:
            _validate_nodeid(nodeid)
        self._init_params = init_params
        self._initial_message = initial_message
        self._actor_cls = actor_cls
        self._wrapper = None
        self._nodeid = nodeid
        self._enable_relay = enable_relay
        self._name = name
        self._keep_running = keep_running

    def startService(self):
        actor_path = self._actor_path = "%s.%s" % (self._actor_cls.__module__, self._actor_cls.__name__)

        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)

        # dbg("Running: %s%s" % (actor_path, " @ /%s" % (self._name,) if self._name else ''))
        spawn(start_actor).link_exception(lambda _: reactor.stop())

    def stopService(self):
        if getattr(self, "node", None):
            self.node.stop()

    def __repr__(self):
        return "<ActorRunner>"
Exemple #4
0
class ActorRunner(Service):
    def __init__(self,
                 actor_cls,
                 init_params={},
                 initial_message=_EMPTY,
                 nodeid=None,
                 enable_relay=False,
                 name=None,
                 keep_running=False):
        if nodeid:
            _validate_nodeid(nodeid)
        self._init_params = init_params
        self._initial_message = initial_message
        self._actor_cls = actor_cls
        self._wrapper = None
        self._nodeid = nodeid
        self._enable_relay = enable_relay
        self._name = name
        self._keep_running = keep_running

    def startService(self):
        actor_path = self._actor_path = '%s.%s' % (self._actor_cls.__module__,
                                                   self._actor_cls.__name__)

        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)

        # dbg("Running: %s%s" % (actor_path, " @ /%s" % (self._name,) if self._name else ''))
        spawn(start_actor).link_exception(lambda _: reactor.stop())

    def stopService(self):
        if getattr(self, 'node', None):
            self.node.stop()

    def __repr__(self):
        return '<ActorRunner>'
Exemple #5
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 #6
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 #7
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 #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_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 #11
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 #12
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 #13
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 #14
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 #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_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 #17
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 #18
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 #19
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 #20
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 #21
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 #22
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 #23
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 #24
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 #25
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 #26
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 #27
0
        def ret():
            # dbg("\n============================================\n")

            import spinoff.actor._actor
            spinoff.actor._actor.TESTING = True

            Actor.reset_flags(debug=True)

            # TODO: once the above TODO (fresh Node for each test fn) is complete, consider making Events non-global by
            # having each Node have its own Events instance.
            Events.reset()

            def check_memleaks():
                if '__pypy__' not in sys.builtin_module_names:
                    gc.collect()
                    for trash in gc.garbage[:]:
                        if isinstance(trash, DebugInfo):
                            # dbg("DEBUGINFO: __del__")
                            if trash.failResult is not None:
                                exc = Unclean(repr(trash.failResult.value) + '\n' + str(trash._getDebugTracebacks()))
                                trash.__dict__.clear()
                                raise exc
                            gc.garbage.remove(trash)

                    assert not gc.garbage, "Memory leak detected: %r" % (gc.garbage,)

                    # if gc.garbage:
                    #     dbg("GARGABE: detected after %s:" % (fn.__name__,), len(gc.garbage))
                    #     import objgraph as ob
                    #     import os

                    #     def dump_chain(g_):
                    #         def calling_test(x):
                    #             if not isframework(x):
                    #                 return None
                    #         import spinoff
                    #         isframework = lambda x: type(x).__module__.startswith(spinoff.__name__)
                    #         ob.show_backrefs([g_], filename='backrefs.png', max_depth=100, highlight=isframework)

                    #     for gen in gc.garbage:
                    #         dump_chain(gen)
                    #         dbg("   TESTWRAP: mem-debuggin", gen)
                    #         import pdb; pdb.set_trace()
                    #         os.remove('backrefs.png')

            return (
                deferred_with(ErrorCollector(), fn)
                .addBoth(lambda result: Node.stop_all().addCallback(lambda _: result))
                .addBoth(lambda result: (_process_idle_calls(), result)[-1])
                .addBoth(lambda result: (check_memleaks(), result)[-1])
            )
Exemple #28
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 #29
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 #30
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 #31
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 #32
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)

            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 #33
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 #34
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 #35
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 #36
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 #37
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 #38
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 #39
0
 def stopService(self):
     yield Node.stop_all()
Exemple #40
0
def DummyNode():
    return Node()
Exemple #41
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'])