Пример #1
0
def start_stop_with(ev_engine: BaseEngine, py_node_name: str):
    """ Starts the local node node, tries to connect to an externally started
        Erlang node, then stops the local node. Checks whether reference to it
        died (whether GC was able to claim it).
        TODO: It doesn't always claim it. Probably not a bug?
    """
    node = Node(node_name=py_node_name + "@127.0.0.1",
                cookie="COOKIE",
                engine=ev_engine)

    fake_pid = node.register_new_process()
    node.send(sender=fake_pid,
              receiver=(Atom('[email protected]'), Atom('shell')),
              message=Atom('hello'))

    ev_engine.sleep(3)

    import weakref
    import gc

    wref = weakref.ref(node)
    node.destroy()
    del node
    gc.collect()
    assert wref() is None, "Reference to node must be dead at this point"
Пример #2
0
    async def link(self, pid1, pid2, local_only=False):
        """ Check each of processes pid1 and pid2 if they are local, mutually
            link them. Assume remote process handles its own linking.

            :param pid1: First pid
            :type pid1: term.pid.Pid
            :param pid2: Second pid
            :type pid2: term.pid.Pid
            :param local_only: If set to True, linking to remote pids will send
                LINK message over dist_proto protocol
        """
        if pid1.is_local_to(self):
            if pid1 in self.processes_:
                self.processes_[pid1].add_link(pid2)
            else:
                # not exists
                await self._send_exit_signal(pid2, pid1, Atom("noproc"))

        elif not local_only:
            link_m = ('link', pid2, pid1)
            await self.dist_command(receiver_node=pid1.node_name_,
                                    message=link_m)

        if pid2.is_local_to(self):
            if pid2 in self.processes_:
                self.processes_[pid2].add_link(pid1)
            else:
                # not exists
                await self._send_exit_signal(pid1, pid2, Atom("noproc"))

        elif not local_only:
            link_m = ('link', pid1, pid2)
            await self.dist_command(receiver_node=pid2.node_name_,
                                    message=link_m)
Пример #3
0
async def example_main(node):
    fake_pid = node.register_new_process()

    # To be able to send to Erlang shell by name first give it a registered
    # name: `erlang:register(shell, self()).`
    # To see an incoming message in shell: `flush().`
    await node.send(sender=fake_pid,
                    receiver=(Atom('[email protected]'), Atom('shell')),
                    message=Atom('hello'))
    LOG.info("example_main: Done")
Пример #4
0
 def handle_one_inbox_message(self, msg):
     if (msg[0] == Atom("stats")):
         rows = c.execute(f'SELECT * FROM registry').fetchall()
         self.get_node().send(sender=self.pid_,
                              receiver=remote_receiver_name(),
                              message=(Atom("stats"), rows))
     if (msg[0] == Atom("received")):
         c.execute(
             f'INSERT INTO registry(device, message) VALUES ("{msg[1]}","{msg[2]}")'
         )
Пример #5
0
def main():
    eng = GeventEngine()
    node = Node(node_name="[email protected]", cookie="PYEX", engine=eng)

    pid = node.register_new_process()

    node.send(sender=pid,
              receiver=(Atom("[email protected]"), Atom("iex")),
              message=Atom("Hello from Python!"))

    eng.run_forever()
Пример #6
0
    def __init__(self):
        self.state = 'init'
        super().__init__()

        self.__timeout_coro = None

        call_match = _atom_match_factory(Atom('$gen_call'))
        cast_match = _atom_match_factory(Atom('$gen_cast'))
        self._match = Match([(call_match, self._pre_handle_call),
                             (cast_match, self._pre_handle_cast),
                             (lambda x: True, self._pre_handle_info)])
Пример #7
0
 def process_loop(self) -> bool:
     """ Returns True to continue running. False to stop. """
     self.handle_inbox()
     if self.i == 30:
         self.node.send(sender=self.pid_,
                        receiver=(Atom('[email protected]'),
                                  Atom('receiver')),
                        message=Atom('test'))
         self.i = 0
     self.i += 1
     return not self.is_exiting_
Пример #8
0
 def exit(self, reason=None):
     LOG.info("TestMonitorProcess: Received EXIT(%s)" % reason)
     node = self.get_node()
     #
     # 3. End, sending a stop message
     #
     LOG.info(color("Stopping remote loop", fg="red"))
     node.send(sender=self.pid_, receiver=remote_receiver_name(),
               message=(Atom("example5"), Atom("stop")))
     LOG.error("Done")
     Process.exit(self, reason)
Пример #9
0
class Server(GenServer):
    """
    Simple GenServer class that handles some data
    """
    def __init__(self):
        super().__init__()
        mypid = self.pid_
        n = self.get_node()
        n.register_name(self, Atom('pysrv'))
        n.send_nowait(mypid, mypid, "register")
        self.other_pid = None

    @call(100, lambda msg: True)
    def handle_call(self, msg):
        LOG.info("got unknown call")
        return "don't understand"

    @call(1, lambda msg: msg == Atom('who_are_you'))
    def who_are_you(self, msg):
        LOG.info("got who are you question")
        return self.get_node().node_name_

    @call(2, lambda msg: msg == Atom('who_is_the_other_one'))
    async def names_do_not_matter(self, msg):
        if not self.other_pid:
            return "don't know yet"
        gsi = GenServerInterface(self, self.other_pid)
        res = await gsi.call(Atom('who_are_you'))
        LOG.info("got response for who are you %s", res)
        return "The other one is", res

    @cast(1,
          lambda msg: type(msg) == tuple and msg[0] == Atom("other_py_node"))
    def call_other_py_node(self, msg):
        other = msg[1]
        LOG.info("got the other py nodes pid %s", other)
        self.other_pid = other

    @cast(100, lambda msg: True)
    def handle_cast(self, msg):
        LOG.info("got unknown cast %s", msg)

    @info(100, lambda msg: True)
    def handle_info(self, msg):
        LOG.info("got unknown info %s", msg)

    @info(0, lambda msg: msg == 'register')
    def register(self, msg):
        LOG.info("registering with erl node")
        n = self.get_node()
        dest = (Atom('[email protected]'), Atom('example8'))
        n.send_nowait(self.pid_, dest, (Atom('register'), self.pid_))
Пример #10
0
def main():
    event_engine = Engine()
    node = Node(node_name="[email protected]", cookie="COOKIE", engine=event_engine)

    fake_pid = node.register_new_process()

    # To be able to send to Erlang shell by name first give it a registered
    # name: `erlang:register(shell, self()).`
    # To see an incoming message in shell: `flush().`
    node.send(sender=fake_pid,
              receiver=(Atom('[email protected]'), Atom('shell')),
              message=Atom('hello'))

    event_engine.run_forever()
Пример #11
0
    def exit(self, reason=None):
        LOG.info("TestLinkProcess: Received EXIT(%s)" % reason)
        node = self.get_node()

        #
        # 2. Create a process P2
        #   Send pid of P2 to remote process example5 and it will monitor P3 and
        #   then will send an exit signal.
        #
        p2 = TestMonitorProcess()
        LOG.info("Sending {example5, test_monitor, %s} to remote 'example5'" % p2.pid_)
        node.send(sender=p2.pid_, receiver=remote_receiver_name(),
                  message=(Atom("example5"), Atom("test_monitor"), p2.pid_))

        Process.exit(self, reason)
Пример #12
0
 def __init__(self, node):
     Process.__init__(self, node.node_name_, passive=False)
     self.node = node
     self.node_name = self.node.node_name_.split("@")[0]
     self.node.register_name(self, Atom(self.node_name))
     self.i = 0
     print("Registering process - {0}".format(self.node.node_name_))
Пример #13
0
 async def names_do_not_matter(self, msg):
     if not self.other_pid:
         return "don't know yet"
     gsi = GenServerInterface(self, self.other_pid)
     res = await gsi.call(Atom('who_are_you'))
     LOG.info("got response for who are you %s", res)
     return "The other one is", res
Пример #14
0
 def __init__(self):
     super().__init__()
     mypid = self.pid_
     n = self.get_node()
     n.register_name(self, Atom('pysrv'))
     n.send_nowait(mypid, mypid, "register")
     self.other_pid = None
Пример #15
0
def main():
    event_engine = Engine()
    node = Node(node_name="[email protected]", cookie="COOKIE", engine=event_engine)

    #
    # 1. Create a process P1
    #   Send pid of P1 to process example5 on the Erlang node with "test_link"
    #   command, it will link remotely and try to kill us and observe the
    #   results (exit signal will be returned to Erlang).
    #
    p1 = TestLinkProcess()
    LOG.info("Sending {example5, test_link, %s} to remote 'example5'" % p1.pid_)
    node.send(sender=p1.pid_, receiver=remote_receiver_name(),
              message=(Atom("example5"), Atom("test_link"), p1.pid_))

    event_engine.run_forever()
Пример #16
0
def main():
    node = Node(node_name="[email protected]", cookie="COOKIE")
    event_loop = node.get_loop()

    #
    # 1. At the same time as P1 (they should not interfere) create a process P2
    #   Send a message to process example7 on the Erlang node with "test_monitor"
    #   command. This will spawn an Erlang process and tell us the pid.
    #   Reply from Erlang node will trigger next steps above in ExampleProcess6
    #
    proc = MonitorExample7()

    LOG.info("Sending {example7, test_monitor, %s} to remote 'example7'" %
             proc.pid_)
    remote_receiver_name = (Atom('[email protected]'), Atom("example7"))
    send_task = node.send(sender=proc.pid_,
                          receiver=remote_receiver_name,
                          message=(Atom("example7"), Atom("test_monitor"),
                                   proc.pid_))

    sleep_sec = 5
    LOG.info("Sleep %d sec" % sleep_sec)

    #
    # 3. End, sending a stop message
    #
    def stop_task():
        LOG.info(color("Stopping remote loop", fg="red"))
        node.send_nowait(sender=proc.pid_,
                         receiver=remote_receiver_name,
                         message=(Atom("example7"), Atom("stop")))

    def destroy_task():
        LOG.error("Destroying")
        node.destroy()
        LOG.error("Done")

    event_loop.create_task(send_task)
    event_loop.call_later(sleep_sec, stop_task)
    event_loop.call_later(2 * sleep_sec, destroy_task)
    node.run()
def main():
    event_engine = Engine()
    node = Node(node_name="[email protected]", cookie="COOKIE", engine=event_engine)

    #
    # 1. At the same time as P1 (they should not interfere) create a process P2
    #   Send a message to process example7 on the Erlang node with "test_monitor"
    #   command. This will spawn an Erlang process and tell us the pid.
    #   Reply from Erlang node will trigger next steps above in ExampleProcess6
    #
    proc = MonitorExample7(node)

    LOG.info("Sending {example7, test_monitor, %s} to remote 'example7'" %
             proc.pid_)
    remote_receiver_name = (Atom('[email protected]'), Atom("example7"))
    node.send(sender=proc.pid_,
              receiver=remote_receiver_name,
              message=(Atom("example7"), Atom("test_monitor"), proc.pid_))

    sleep_sec = 5
    LOG.info("Sleep %d sec" % sleep_sec)
    event_engine.sleep(sleep_sec)

    #
    # 3. End, sending a stop message
    #
    LOG.info(color("Stopping remote loop", fg="red"))
    node.send(sender=proc.pid_,
              receiver=remote_receiver_name,
              message=(Atom("example7"), Atom("stop")))

    event_engine.sleep(sleep_sec)
    node.destroy()
    LOG.error("Done")
Пример #18
0
def main():
    node = Node(node_name="[email protected]", cookie="COOKIE")
    event_loop = node.get_loop()

    #
    # 1. Create a process P1
    #   Send a message to process example6 on the Erlang node with "test_link"
    #   command. This will spawn an Erlang process and tell us the pid.
    #   Reply from Erlang node will trigger next steps above in ExampleProcess6
    #
    p1 = LinkExample6()

    LOG.info("Sending {example6, test_link, %s} to remote 'example6'" % p1.pid_)
    remote_receiver_name = (Atom('[email protected]'), Atom("example6"))

    def send_task():
        node.send_nowait(sender=p1.pid_,
                         receiver=remote_receiver_name,
                         message=(Atom("example6"), Atom("test_link"), p1.pid_))

    sleep_sec = 5
    LOG.info("Sleep %d sec" % sleep_sec)

    #
    # 3. End, sending a stop message
    #
    def task_sleep1():
        LOG.info(color("Stopping remote loop", fg="red"))
        node.send_nowait(sender=p1.pid_,
                         receiver=remote_receiver_name,
                         message=(Atom("example6"), Atom("stop")))

    def task_sleep2():
        node.destroy()
        LOG.error("Done")

    event_loop.call_soon(send_task)
    event_loop.call_later(sleep_sec, task_sleep1)
    event_loop.call_later(2 * sleep_sec, task_sleep2)
    node.run()
Пример #19
0
def main():
    event_engine = Engine()
    node = Node(node_name="[email protected]", cookie="COOKIE", engine=event_engine)

    #
    # 1. Create a process P1
    #   Send a message to process example6 on the Erlang node with "test_link"
    #   command. This will spawn an Erlang process and tell us the pid.
    #   Reply from Erlang node will trigger next steps above in ExampleProcess6
    #
    p1 = LinkExample6()

    LOG.info("Sending {example6, test_link, %s} to remote 'example6'" %
             p1.pid_)
    remote_receiver_name = (Atom('[email protected]'), Atom("example6"))
    node.send(sender=p1.pid_,
              receiver=remote_receiver_name,
              message=(Atom("example6"), Atom("test_link"), p1.pid_))

    sleep_sec = 5
    LOG.info("Sleep %d sec" % sleep_sec)
    event_engine.sleep(sleep_sec)

    #
    # 3. End, sending a stop message
    #
    LOG.info(color("Stopping remote loop", fg="red"))
    node.send(sender=p1.pid_,
              receiver=remote_receiver_name,
              message=(Atom("example6"), Atom("stop")))

    event_engine.sleep(sleep_sec)
    node.destroy()
    LOG.error("Done")
Пример #20
0
    def handle_one_inbox_message(self, msg):
        #
        # 1.1. Erlang node spawned a process for us and replied with a Pid
        #
        if isinstance(msg, tuple) and msg[0] == Atom("test_link"):
            LOG.info("LinkExample6: Linking to %s and killing", msg)
            n = self.get_node()
            n.link_nowait(self.pid_, msg[1])

            def exit_fn():
                n.exit_process(sender=self.pid_, receiver=msg[1],
                               reason=Atom("example6_link_exit"))
            loop = self.get_node().get_loop()
            loop.call_later(0.5, exit_fn)
        else:
            LOG.info("LinkExample6: Incoming %s", msg)
    def handle_one_inbox_message(self, msg):
        #
        # 1.1. Erlang node spawned a process for us and replied with a Pid
        #
        if isinstance(msg, tuple) and msg[0] == Atom("test_monitor"):
            LOG.info("MonitorExample7: Monitoring %s and killing", msg)
            n = self.get_node()
            n.monitor_process(self.pid_, msg[1])

            def exit_fn():
                n.exit_process(sender=self.pid_,
                               receiver=msg[1],
                               reason=Atom("example7_monitor_exit"))

            self.engine_.call_later(0.5, exit_fn)
        else:
            LOG.info("MonitorExample7: Incoming %s", msg)
Пример #22
0
    def destroy(self):
        """ Closes incoming and outgoing connections and destroys the local
            node. This is Python, so some refs from running async handlers
            may remain.
        """
        self.is_exiting_ = True

        import copy
        all_processes = copy.copy(self.processes_)
        for p in all_processes.values():
            p.exit(Atom('killed'))
        self.processes_.clear()
        self.reg_names_.clear()

        for dproto in self.dist_nodes_.values():
            dproto.destroy()
        self.dist_nodes_.clear()

        self.dist_.destroy()
        self.node_db.remove(self.node_name_)
        self.__completed_future.set_result(True)
        del self
Пример #23
0
 async def cast(self, request):
     calling_pid = self._calling_process.pid_
     msg = (Atom('$gen_cast'), request)
     await self._node.send(calling_pid, self._destination_pid, msg)
Пример #24
0
 def __init__(self, node) -> None:
     Process.__init__(self, node_name=node.node_name_)
     node.register_name(self, Atom('mailbox'))
Пример #25
0
def remote_receiver_name():
    return Atom('orchestrator@localhost'), Atom("orchestrator")
Пример #26
0
 def __init__(self) -> None:
     Process.__init__(self)
     self.get_node().register_name(self, Atom('my_process'))  # optional
     LOG.info("Registering process - 'my_process'")
Пример #27
0
def remote_receiver_name():
    return Atom('[email protected]'), Atom("example5")
Пример #28
0
 def _timeout(self):
     """Internal function see `timeout`"""
     self.inbox_.put_nowait(Atom('timeout'))
Пример #29
0
 async def call(self, request, timeout=None):
     return await self._do_call(Atom('$gen_call'), request, timeout)
Пример #30
0
 def exit_fn():
     n.exit_process(sender=self.pid_,
                    receiver=msg[1],
                    reason=Atom("example6_link_exit"))