Shutdown an SimpleXMLRPCServer server in python
Asked Answered
F

2

9

Currently I am writing an application using the SimpleXMLRPCServer module in Python.

The basic aim of this application is to keep running on a server and keep checking a Queue for any task. If it encounters any new request in the Queue, serve the request.

Snapshot of what I am trying to do :

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

Main

if name == "main":

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

Once the server is started it remains in the loop forever inside do_some_task method to keep checking the Queue for any task. This is what i wanted to achieve. But now i want to gracefully shutdown the server. In this case i am unable to shutdown the server.

Till now I have Tried using a global flag STOP_SERVER for 'True' and checking its status in the do_some_task while loop to get out of it and stop the server. But no help.

Tried using SHUTDOWN() method of the SimpleXMLRPCServer but it seems it is getting into a infinite loop of somekind.

Could you suggest some proper way to gracefully shutdown the server.

Thanks in advance

Flats answered 24/9, 2015 at 12:55 Comment(2)
From the shutdown() docstring: „Blocks until the loop has finished. This must be called while serve_forever() is running in another thread, or it will deadlock.“Anthelmintic
@Anthelmintic With serve_forever() running in another thread, catching a signal and running shutdown() does nothing...Coliseum
F
4

You should use handle_request() instead of serve_forever() if you want to close it manualy. Because SimpleXMLRPCServer is implemented as a single thread and the serve_forever() will make the server instance run into an infinite loop.

You can refer to this article. This is an example cited from there:

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()

By using handle_request(), this code use a state variable self.quit to indicate whether to quit the infinite loop.

Fernald answered 25/11, 2019 at 10:1 Comment(0)
W
4

The serve_forever function is inherited from a base class in the socketserver module called BaseServer. If you look at this fucntion you'll see it has an attribute called __shutdown_request, and this can be used to break the serving while loop. Because of the double underscore you'll have to access the variable with its mangled name: _BaseServer__shutdown_request.

Putting that all together you can make a very simple quit function as follows:

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
Whose answered 30/11, 2021 at 16:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.