python - 用正确的方法包装Pyro的NameServer

标签 python multithreading nameservers pyro

我正在尝试将Pyro的名称服务器转换为更方便的对象,该对象可以让我根据需要启动和停止它。例如,我希望能够做类似的事情

nameServer = NameServer("localhost")
nameServer.startNS()

[... make some other operations...]

nameServer.stopNS()        
nameServer = None


[... make some other operations...]

nameServer = NameServer("localhost")
nameServer.startNS()

对NameServer类使用以下定义:
class NameServer(threadutil.Thread):
    def __init__(self, host, isDeamon=True, port=None, enableBroadcast=True, 
                 bchost=None, bcport=None, unixsocket=None, nathost=None, natport=None):
        super(NameServer,self).__init__()
        self.setDaemon(isDeamon)
        self.host=host
        self.started=threadutil.Event()
        self.unixsocket = unixsocket

        self.port = port
        self.enableBroadcast = enableBroadcast 
        self.bchost = bchost
        self.bcport = bcport
        self.nathost = nathost
        self.natport = natport


        """
         This code is taken from Pyro4.naming.startNSloop
        """
        self.ns_daemon = naming.NameServerDaemon(self.host, self.port, self.unixsocket, 
                                                 nathost=self.nathost, natport=self.natport)
        self.uri    = self.ns_daemon.uriFor(self.ns_daemon.nameserver)
        internalUri = self.ns_daemon.uriFor(self.ns_daemon.nameserver, nat=False)
        self.bcserver=None
        if self.unixsocket:
            hostip = "Unix domain socket"
        else:
            hostip = self.ns_daemon.sock.getsockname()[0]
            if hostip.startswith("127."):
                enableBroadcast=False
            if enableBroadcast:
                # Make sure to pass the internal uri to the broadcast responder.
                # It is almost always useless to let it return the external uri,
                # because external systems won't be able to talk to this thing anyway.
                bcserver=naming.BroadcastServer(internalUri, self.bchost, self.bcport)
                bcserver.runInThread()


    def run(self):
        try:
            self.ns_daemon.requestLoop()
        finally:
            self.ns_daemon.close()
            if self.bcserver is not None:
                self.bcserver.close()


    def startNS(self):
        self.start()

    def stopNS(self):
        self.ns_daemon.shutdown()
        if self.bcserver is not None:
            self.bcserver.shutdown()

到目前为止,一切都很好。它按预期工作。但是,如果在名称服务器运行时从另一个线程运行Pyro4.naming.locateNS()命令,则下次我调用nameServer.stopNS()时,程序将冻结。有人知道为什么吗?编写这样的NameServer包装器的最佳方法(至少是更好的方法)是什么。

最佳答案

Pyro4存储库中有一个您可以改编的示例。

https://github.com/delmic/Pyro4/blob/master/examples/eventloop/server.py

from __future__ import print_function
import socket
import select
import sys
import Pyro4.core
import Pyro4.naming

if sys.version_info<(3,0):
    input=raw_input

print("Make sure that you don't have a name server running already.")
servertype=input("Servertype thread/multiplex (t/m)?")
if servertype=='t':
    Pyro4.config.SERVERTYPE="thread"
else:
    Pyro4.config.SERVERTYPE="multiplex"

hostname=socket.gethostname()

class EmbeddedServer(object):
    def multiply(self, x, y):
    return x*y


print("initializing services... servertype=%s" % Pyro4.config.SERVERTYPE)
# start a name server with broadcast server as well
nameserverUri, nameserverDaemon, broadcastServer = Pyro4.naming.startNS(host=hostname)
assert broadcastServer is not None, "expect a broadcast server to be created"

print("got a Nameserver, uri=%s" % nameserverUri)
print("ns daemon location string=%s" % nameserverDaemon.locationStr)
print("ns daemon sockets=%s" % nameserverDaemon.sockets)
print("bc server socket=%s (fileno %d)" % (broadcastServer.sock, broadcastServer.fileno()))

# create a Pyro daemon
pyrodaemon=Pyro4.core.Daemon(host=hostname)
print("daemon location string=%s" % pyrodaemon.locationStr)
print("daemon sockets=%s" % pyrodaemon.sockets)

# register a server object with the daemon
serveruri=pyrodaemon.register(EmbeddedServer())
print("server uri=%s" % serveruri)

# register it with the embedded nameserver directly
nameserverDaemon.nameserver.register("example.embedded.server",serveruri)

print("")

# below is our custom event loop.
while True:
    print("Waiting for events...")
    # create sets of the socket objects we will be waiting on
    # (a set provides fast lookup compared to a list)
    nameserverSockets = set(nameserverDaemon.sockets)
    pyroSockets = set(pyrodaemon.sockets)
    rs=[broadcastServer] # only the broadcast server is directly usable as a select() object
    rs.extend(nameserverSockets)
    rs.extend(pyroSockets)
    rs,_,_ = select.select(rs,[],[],3)
    eventsForNameserver=[]
    eventsForDaemon=[]
    for s in rs:
    if s is broadcastServer:
        print("Broadcast server received a request")
        broadcastServer.processRequest()
    elif s in nameserverSockets:
        eventsForNameserver.append(s)
    elif s in pyroSockets:
        eventsForDaemon.append(s)
    if eventsForNameserver:
    print("Nameserver received a request")
    nameserverDaemon.events(eventsForNameserver)
    if eventsForDaemon:
    print("Daemon received a request")
    pyrodaemon.events(eventsForDaemon)


nameserverDaemon.close()
broadcastServer.close()
pyrodaemon.close()
print("done")

关于python - 用正确的方法包装Pyro的NameServer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19394228/

相关文章:

java - Java中全局锁的实现

linux - 如何在CentOS上设置域名服务器?

php - 通过 http 请求从名称服务器获得响应?

python - 只有四个元素在 python 中出现内存错误

python - 在DataFrame的开头(最左端)插入一列

python - sess.run(Tensor()) 不执行任何操作

python - 文件中生成的词干列表 Tor 电路

c - 在多线程生产者和消费者应用程序中读取时发生访问冲突

amazon-web-services - 在 AWS 路由 53 上配置通配符记录

Java 线程未异步运行 - 有些根本未完成