Python Pyro4 nameserver freezes when adding more than two remote objects

1.2k Views Asked by At

Say I want to ping something from different locations, so I wrap ping commandline tool into python and use pyro4 prc library to call it.

I have a python Pyro4 nameserver

import Pyro4
Pyro4.config.COMPRESSION = True
Pyro4.naming.startNSloop("ipofnameserver")

And simple ping server:

class Pinger(object):
    def ping(self, host):
        return subprocess.check_output(["ping", host, "-c 4"])

pinger = Pinger()

daemon = Pyro4.Daemon()                 # make a Pyro daemon
ns  = Pyro4.locateNS(host = "ipofnameservre", port=9090) # find the name server
uri = daemon.register(pinger)   # register the greeting object as a Pyro object
print ns.register("location1", uri) 
print "Ready. Object uri =", uri      # print the uri so we can use it in the client later
daemon.requestLoop()    

As long as I have only two pingservers everything is ok, but after I add third one nameserver stop responding. Every pingserver has unique name of course.

For example, I want to check availability of the servers:

ns  = Pyro4.locateNS(host = "nameserverip", port=9090)
names = ns.list().keys()
print names
print ns.list()
for n in names:
    if n == 'Pyro.NameServer': continue
    proxy = Pyro4.Proxy("PYRONAME:"+n)
    try:
        print n, proxy._Proxy__pyroCreateConnection()
    except:
        print "offline"

This works with two pingservers, but with three it just waits for something. Traceback of this script terminated with ctrl+C:

   ns  = Pyro4.locateNS(host = "nameserverip", port=9090)
  File "/usr/local/lib/python2.7/dist-packages/Pyro4/naming.py", line 319, in locateNS
    proxy.ping()
  File "/usr/local/lib/python2.7/dist-packages/Pyro4/core.py", line 146, in __call__
    return self.__send(self.__name, args, kwargs)
  File "/usr/local/lib/python2.7/dist-packages/Pyro4/core.py", line 250, in _pyroInvoke
    self.__pyroCreateConnection()
  File "/usr/local/lib/python2.7/dist-packages/Pyro4/core.py", line 312, in __pyroCreateConnection
    msgType, flags, seq, data = MessageFactory.getMessage(conn, None)
  File "/usr/local/lib/python2.7/dist-packages/Pyro4/core.py", line 665, in getMessage
    headerdata = connection.recv(cls.HEADERSIZE)
  File "/usr/local/lib/python2.7/dist-packages/Pyro4/socketutil.py", line 323, in recv
    return receiveData(self.sock, size)
  File "/usr/local/lib/python2.7/dist-packages/Pyro4/socketutil.py", line 104, in receiveData
    data=sock.recv(size, socket.MSG_WAITALL)

strace shows the following:

socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3 fcntl(3, F_GETFL)
= 0x2 (flags O_RDWR) fcntl(3, F_SETFL, O_RDWR) = 0 connect(3, {sa_family=AF_INET, sin_port=htons(9090), sin_addr=inet_addr("ipofnameserver")}, 16) = 0 setsockopt(3, SOL_SOCKET, SO_KEEPALIVE, [1], 4) = 0 recvfrom(3,

The following example is not working either, as it unable to resolve names into pyro_uri, because it just waits for something like in previous example. Interesting thing about this example that it prints fls, which contains names of all remote pingservers. Then adding fourth pingserver I'm unable even to print names of registered pingservers.

def _ping((host, firing_location)):
    pinger = Pyro4.Proxy("PYRONAME:" + firing_location)
    return pinger.ping(host)

def ping(host):
    ns  = Pyro4.locateNS(host = "178.209.52.240", port=9090)
    names = ns.list().keys()
    fls = []
    for name in names:
        if name == 'Pyro.NameServer': continue
        fls.append(name)
    print fls
    p = Pool(len(fls))
    jobs = p.map(_ping, zip([host]*len(fls), fls) )
    for j in jobs:
        print j.split("/")[-3], "±", j.split("/")[-1][:-1]
    return jobs

I'm struggling with it for two days and have no idea of what's wrong with my code.

0

There are 0 best solutions below