Exemple #1
0
 def _PingEpmdResponse(self, result, portNum, nodeType, proto, distVSNRange,
                       nodeNameNoHost, extra, remoteNodeName):
     """This callback is called when the lookup for a nodename at a host
     has returned, whether it was successful or not.
     If it was successful, then RESULT != 0 and the other parameters
     are valid. If it was not successful, then the other parameters have
     undefined values."""
     if result != 0:
         callbacks = self._ongoingPings[remoteNodeName]
         del self._ongoingPings[remoteNodeName]
         for cb in callbacks:
             cb("pang")
     else:
         [otherNode, otherHost] = remoteNodeName.split("@")
         out = erl_node_conn.ErlNodeOutConnection(self._nodeName,
                                                  self._opts)
         connectedOkCb = erl_common.Callback(self._PingSucceeded, out,
                                             remoteNodeName)
         connectFailedCb = erl_common.Callback(self._PingFailed, out,
                                               remoteNodeName)
         connectionBrokenCb = erl_common.Callback(self._NodeDown, out,
                                                  remoteNodeName)
         passThroughMsgCb = erl_common.Callback(self._PassThroughMsg, out,
                                                remoteNodeName)
         out.InitiateConnection(otherHost, portNum, connectedOkCb,
                                connectFailedCb, connectionBrokenCb,
                                self._PassThroughMsg)
Exemple #2
0
    def Ping(self, remoteNodeName, pingCallback):
        """Ping a remote node.

        REMOTE-NODE-NAME        = string | <instance of ErlAtom>
                                The node to ping
        PING-CALLBACK           = <function(RESULT): void>
                                A callback to call for deliverance of the
                                ping result. RESULT = "pong" | "pang".

        Returns: void
        Throws:  <<to-be-documented>>

        Try to ping a remote node. A connection to that node is established
        unless already connected. Whether or not the remote node is up or
        down is indicated as by the argument to the callback function:
          "pong": the remote node is alive and there is a connection to it
          "pang": the remote node is down.
        """
        if not "@" in remoteNodeName:
            raise ErlNodeBadPeerNameError(remoteNodeName)
        if remoteNodeName in self._ongoingPings:
            pingCallbacks = self._ongoingPings[remoteNodeName]
            self._ongoingPings[remoteNodeName] = pingCallbacks + [pingCallback]
        else:
            self._ongoingPings[remoteNodeName] = [pingCallback]
            [nodeName, hostName] = remoteNodeName.split("@")
            e = erl_epmd.ErlEpmd(hostName)
            cb = erl_common.Callback(self._PingEpmdResponse, remoteNodeName)
            e.PortPlease2Req(nodeName, cb)
Exemple #3
0
def main(argv):
    global mb, quiet, node_to_connect_to

    try:
        opts, args = getopt.getopt(argv[1:], "?dn:c:qr:")
    except getopt.error as info:
        print(info)
        sys.exit(1)

    hostName = "localhost"
    ownNodeName = "py_interface_test"
    cookie = "cookie"
    doDebug = 0

    for (optchar, optarg) in opts:
        if optchar == "-?":
            print("Usage: %s erlnode" % argv[0])
            sys.exit(1)
        elif optchar == "-c":
            cookie = optarg
        elif optchar == "-d":
            doDebug = 1
        elif optchar == "-q":
            quiet = 1
        elif optchar == "-n":
            ownNodeName = optarg
        elif optchar == "-r":
            global res_pidname
            res_pidname = optarg

    if len(args) >= 4:
        node_to_connect_to = args[0]
        mod = args[1]
        fn = args[2]
        args = eval(args[3])
    else:
        print("Error: missing args: " + "node_to_connect_to mod fn args")
        sys.exit(1)

    if doDebug:
        erl_common.DebugOnAll()

    print("Creating node...")
    n = erl_node.ErlNode(ownNodeName, erl_opts.ErlNodeOpts(cookie=cookie))
    n.SetEpmdConnectedOkCb(
        erl_common.Callback(__EpmdConnectedOk, node_to_connect_to, mod, fn,
                            args, __RpcResult))
    print("Publishing node...")
    n.Publish()
    print("Creating mbox...")
    mb = n.CreateMBox(None)
    m = n.CreateMBox(__TestMBoxCallback)

    evhand = erl_eventhandler.GetEventHandler()
    evhand.PushReadEvent(sys.stdin, __FlushStdout)

    print("-GOING LOOPING-")  # Erlang side will pick this text up
    sys.stdout.flush()

    evhand.Loop()
Exemple #4
0
 def KillReq(self, callback):
     """Issue a Kill request
     CALLBACK = <function(RESPONSE): void
                RESPONSE = string
     Calls the CALLBACK when the answer is available.
     """
     msg = self.PackInt1(self._KILL_REQ)
     unpackcb = erl_common.Callback(self._UnpackKillResp, callback)
     self._SendOneShotReq(msg, unpackcb)
Exemple #5
0
 def DumpReq(self, callback):
     """Issue a Dump request
     CALLBACK = <function(EPMD-PORT-NUM, NODE-INFO): void
                EPMD-PORT-NUM = NODE-INFO = integer
     Calls the CALLBACK when the answer is available.
     """
     msg = self.PackInt1(self._DUMP_REQ)
     unpackcb = erl_common.Callback(self._UnpackDumpResp, callback)
     self._SendOneShotReq(msg, unpackcb)
Exemple #6
0
    def send_async_rpc(self, remote_node, module, function, args,
        callback=_TestMBoxRPCResponse):
 
        self._event_handler.AddTimerEvent(0.001,
            erl_common.Callback(send_rpc,
                self._mbox,
                remote_node,
                module,
                function,
                args,
                callback))
Exemple #7
0
 def PortPleaseReq(self, nodeName, callback):
     """Issue a PortPlease request.
     NODE-NAME = string
     CALLBACK  = <function(PORT-NUMBER): void>
                 PORT-NUMBER = integer
     Calls the CALLBACK function with argument PORT-NUMBER when
     the answer is available.
     """
     msg = self.PackInt1(self._PORT_PLEASE_REQ) + nodeName
     unpackcb = erl_common.Callback(self._UnpackPortPleaseResp, callback)
     self._SendOneShotReq(msg, unpackcb)
Exemple #8
0
    def __init__(self, nodeName, opts=erl_opts.ErlNodeOpts()):
        """Constructor.

        NODE-NAME       = string
                        The name for this node.

        OPTS            = <instance of ErlNodeOpts>

        Creates an ErlNode. The name of the node is determined by NODE-NAME
        as described below. A node-name consists of two parts: an alive-name
        and a host-name, separated by an `@'. The host-name can be short
        (not including the domain) or long (including the domain). Short and
        long node-names must not be mixed among the nodes in a system, see
        the erlang documentation for further details.
          1. If the NODE-NAME contains an `@', then NODE-NAME is used
             unchanged as name for the node.
          2. If the NODE-NAME does not contain an `@', then the node's name
             is constructed as NODE-NAME + "@" + host-name, where
             host-name is either on short or long form, depending on what is
             specified in the OPTS.
        """
        shortNodeNames = opts.GetShortNodeNames()
        self._nodeName = erl_common.AlignNodeName(nodeName, shortNodeNames)
        self._opts = opts

        self._creation = 0
        self._connections = {}

        self._epmd = erl_epmd.ErlEpmd(hostName=opts.GetEpmdHost(),
                                      portNum=opts.GetEpmdPort())
        self._ongoingPings = {}

        self._isServerPublished = 0
        self._pids = {}  # mapping pid     --> ErlMBox()
        self._mboxes = {}  # mapping ErlMBox --> pid
        self._registeredNames = {}  # mapping name    --> pid
        self._registeredPids = {}  # mapping pid     --> name

        self._nodeUpCb = []  # stores (id, callback)
        self._nodeDownCb = []  # stores (id, callback)
        self._cbId = 0

        self._server = erl_node_conn.ErlNodeServerSocket(
            self._nodeName, self._opts)
        self._portNum = self._server.Start(self._NodeUp, self._NodeDown,
                                           self._PassThroughMsg)
        self._epmd.SetOwnPortNum(self._portNum)
        self._epmd.SetOwnNodeName(self._nodeName)
        self._epmdConnectedOkCb = erl_common.Callback(self._Sink)
        self._CreateRex()
Exemple #9
0
    def send_async_rpcs(self, rpcs):
        output_queue = Queue.Queue()

        def callback(msg):
            output_queue.put(msg)

        for rpc in rpcs: 
            self._event_handler.AddTimerEvent(0.001,
                erl_common.Callback(send_rpc,
                    self._mbox,
                    rpc[0], # remote_node,
                    rpc[1], # module,
                    rpc[2], # function,
                    rpc[3], # args,
                    callback))

        return output_queue
Exemple #10
0
    def PortPlease2Req(self, nodeName, callback):
        """Issue a PortPlease2 request.
        NODE-NAME = string
        CALLBACK  = <function(RESULT, NODE-TYPE, PROTOCOL, DISTR-VSN-RANGE,
                              RNODE-NAME, EXTRA): void>
                    RESULT = 1 | 0
                    NODE-TYPE = integer
                    PROTOCOL = integer
                    DISTR-VSN-RANGE = tuple(LO, HI)
                    LO = HI = integer
                    RNODE-NAME = string
                    EXTRA = string
        Calls the CALLBACK function when the answer is available from the EPMD.
        If the RESULT is 0, then the values of the rest of the arguments
        are undefined. If the result is 1, then the rest of the arguments
        have the values as reported from the EPMD.

        Calls the CALLBACK function with argument PORT-NUMBER when
        the answer is available.
        """
        msg = self.PackInt1(self._PORT_PLEASE2_REQ) + nodeName
        unpackcb = erl_common.Callback(self._UnpackPortPlease2Resp, callback)
        self._SendOneShotReq(msg, unpackcb)
Exemple #11
0
    def send_sync_rpc(self, remote_node, module, function, args, timeout=None):
        # Cleaning queue in case callback called right after timeout
        if self._sync_rpc_queue.full():
            LOGGER.debug("Cleaning sync rpc queue")
            self._sync_rpc_queue.get()

        timer_id = self._event_handler.AddTimerEvent(0.001,
            erl_common.Callback(send_rpc,
                self._mbox,
                remote_node,
                module,
                function,
                args,
                self._sync_rpc_callback))

        if timeout is None:
            timeout = self._timeout     
 
        try:
            msg = self._sync_rpc_queue.get(True, timeout)
        except Queue.Empty as error:
            self._event_handler.DelTimerEvent(timer_id)
            raise Timeout("No response for sync rpc.")
        return msg
Exemple #12
0
def set_timeout(event_handler, timeout):
    event_handler.AddTimerEvent(timeout,
        erl_common.Callback(_DoTimeout, event_handler))
Exemple #13
0
    print "Publishing node..."
    n.Publish()
    print "Creating mbox..."
    m = n.CreateMBox(__TestMBoxCallback)
    print "Registering mbox as p..."
    m.RegisterName("p")

    evhand = erl_eventhandler.GetEventHandler()
    eh = evhand

    evhand.AddTimerEvent(timeout, DoTimeout)

    # Schedule to run the RPC after we've started looping
    evhand.AddTimerEvent(
        0.001,
        erl_common.Callback(SendTheRPC, m, remoteNode, module, function,
                            map(lambda x: ExprRebuildAtoms(eval(x)), fargs)))
    """import threading
    threading.Thread(target = evhand.AddTimerEvent,args=(0.001,
                         erl_common.Callback(
                             SendTheRPC, m, remoteNode,
                             module, function,
                             map(lambda x: ExprRebuildAtoms(eval(x)),
                                 fargs)))).start()"""
    print "Looping..."
    #threading.Thread(target=evhand.Loop,args=()).start()
    evhand.Loop()
    sys.exit(0)


try:
    main(sys.argv)
Exemple #14
0
 def StopReq(self, nodeName, callback):
     raise "Not used"
     msg = self.PackInt1(self._STOP_REQ) + nodeName
     unpackcb = erl_common.Callback(self._UnpackStopResp, callback)
     self._SendOneShotReq(msg, unpackcb)
Exemple #15
0
    def SendMsgFromMBox(self, sourceMBox, dest, msg):
        """This routine is intended to be called from an ErlMBox instance
        SOURCE-MBOX = <instance of ErlMBox>
        DEST        = <instance of ErlPid> |
                      string |
                      <instance of ErlAtom> |
                      tuple(DEST-REGNAME, DEST-NODE)
                      DEST-REGNAME = DEST-NODE = string | <instance of ErlAtom>
        MSG         = <term>
        Returns: void
        THrows:  <<to-be-documented>>
        """
        ## Possible dest types:
        ## - A tuple: (registered_name, node_name)
        ## - An atom: registered_name
        ## - A pid:   <erlpid ...>  (note: the pid contains the pid's node)

        sourcePid = self._mboxes[sourceMBox]

        ## First check for strings in the dest argument.
        ## Convert any strings to to atoms.
        if type(dest) == str or type(dest) == bytes:
            dest = erl_term.ErlAtom(dest)
        elif type(dest) == tuple:
            destPidName = dest[0]
            destNode = dest[1]
            if type(destPidName) == str or type(destPidName) == bytes:
                destPidName = erl_term.ErlAtom(destPidName)
            if type(destNode) == str or type(destNode) == bytes:
                destNode = erl_term.ErlAtom(destNode)
            dest = (destPidName, destNode)

        ## Then split the dest into:
        ##    destPid/destPidName   and   destNode
        ## depending on its type.
        if type(dest) == tuple:
            destPid = dest[0]
            destNode = dest[1]
        elif erl_term.IsErlAtom(dest):
            destNode = self
            name = dest.atomText
            if name not in self._registeredNames:
                return
            destPid = self._registeredNames[name]
        elif erl_term.IsErlPid(dest):
            destPid = dest
            destNode = dest.node
        else:
            return

        ## Now do the sending...
        if destNode == self:
            if destPid not in self._registeredPids:
                return
            mbox = self._registredPids[destPid]
            mbox.Msg(msg)
        else:  # dest node is remote
            # First make sure we are online
            # FIXME: Will this really work???
            #        Publish might register callbacks, but
            #        this code continues after the Publish...
            self.Publish()
            destNodeName = destNode.atomText
            if destNodeName not in self._connections:
                # We don't have a connection to the destination
                # We must open a connection.
                # This is done by pinging with the ping-callback
                # being a function that sends the message.

                cb = erl_common.Callback(self._SendMsgToRemoteNode, sourcePid,
                                         destNode, destPid, msg)
                destNodeName = destNode.atomText
                self.Ping(destNodeName, cb)
            else:
                ## We have contact with the remote node. Send at once!
                self._SendMsgToRemoteNode("pong", sourcePid, destNode, destPid,
                                          msg)
Exemple #16
0
 def StopReq(self, nodeName, callback):
     nodeName = nodeName.encode("latin1")
     msg = self.PackInt1(self._STOP_REQ) + nodeName
     unpackcb = erl_common.Callback(self._UnpackStopResp, callback)
     self._SendOneShotReq(msg, unpackcb)