关闭Python中的SimpleXMLRPCServer服务器

8

目前我正在使用Python中的SimpleXMLRPCServer模块编写一个应用程序。

这个应用程序的基本目的是在服务器上保持运行并检查队列中是否有任何任务。如果遇到队列中的任何新请求,则服务该请求。

我尝试做的事情的快照:

class MyClass():

"""
This class will have methods which will be exposed to the clients
"""
def __init__(self):
    taskQ = Queue.Queue()

def do_some_task(self):
    while True:
         logging.info("Checking the Queue for any Tasks..")
         task = taskQ.get()
         # Do some processing based on the availability of some task

主函数

如果 name 等于 "main":

server = SimpleXMLRPCServer.SimpleXMLRPCServer((socket.gethostname(), Port)
classObj = MyClass()
rpcserver.register_function(classObj.do_some_task)
rpcserver.serve_forever()

一旦服务器启动,它将永远停留在 do_some_task 方法内的循环中,以继续检查队列中是否有任务。这就是我想要实现的。但是现在我想要优雅地关闭服务器。在这种情况下,我无法关闭服务器。
到目前为止,我已经尝试使用一个名为 STOP_SERVER 的全局标志来检查它的状态是否为 “True”,并在 do_some_task 循环中退出并停止服务器。但是没有帮助。
尝试使用 SimpleXMLRPCServer 的 SHUTDOWN() 方法,但似乎进入了某种无限循环。
请您建议一些适当的方式优雅地关闭服务器。
提前感谢。

shutdown()的文档字符串中:“阻塞直到循环完成。必须在serve_forever()在另一个线程中运行时调用此函数,否则会死锁。” - BlackJack
@BlackJack 在另一个线程中运行 serve_forever(),捕获信号并运行 shutdown() 没有任何作用... - Six
2个回答

3
serve_forever函数继承自socketserver模块中的一个基类BaseServer。如果您查看此函数,您会发现它有一个名为__shutdown_request的属性,可以用来打破服务while循环。由于有双下划线,您必须使用其混淆名称访问变量:_BaseServer__shutdown_request

将所有内容组合在一起,您可以编写一个非常简单的退出函数,如下所示:

from xmlrpc.server import SimpleXMLRPCServer

class MyXMLRPCServer(SimpleXMLRPCServer):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.register_function(self.quit)
    
    def quit(self):
        self._BaseServer__shutdown_request = True
        return 0

3
如果您想要手动关闭它,应该使用handle_request()而不是serve_forever()。因为SimpleXMLRPCServer是作为单个线程实现的,而serve_forever()将使服务器实例陷入无限循环。
您可以参考这篇文章。这里引用了其中的一个例子:
from SimpleXMLRPCServer import *

class MyServer(SimpleXMLRPCServer):

    def serve_forever(self):
        self.quit = 0
        while not self.quit:
            self.handle_request()


def kill():
    server.quit = 1
    return 1


server = MyServer(('127.0.0.1', 8000))
server.register_function(kill)

server.serve_forever()

通过使用 handle_request(),这段代码使用一个状态变量self.quit来指示是否退出无限循环。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接