How to stop BaseHTTPServer.serve_forever() in a BaseHTTPRequestHandler subclass?
I should start by saying that "I probably wouldn't do this myself, but I have in the past". The serve_forever (from SocketServer.py) method looks like this:
def serve_forever(self): """Handle one request at a time until doomsday.""" while 1: self.handle_request()
You could replace (in subclass) while 1
with while self.should_be_running
, and modify that value from a different thread. Something like:
def stop_serving_forever(self): """Stop handling requests""" self.should_be_running = 0 # Make a fake request to the server, to really force it to stop. # Otherwise it will just stop on the next request. # (Exercise for the reader.) self.make_a_fake_request_to_myself()
Edit: I dug up the actual code I used at the time:
class StoppableRPCServer(SimpleXMLRPCServer.SimpleXMLRPCServer): stopped = False allow_reuse_address = True def __init__(self, *args, **kw): SimpleXMLRPCServer.SimpleXMLRPCServer.__init__(self, *args, **kw) self.register_function(lambda: 'OK', 'ping') def serve_forever(self): while not self.stopped: self.handle_request() def force_stop(self): self.server_close() self.stopped = True self.create_dummy_request() def create_dummy_request(self): server = xmlrpclib.Server('http://%s:%s' % self.server_address) server.ping()
Another way to do it, based on http://docs.python.org/2/library/basehttpserver.html#more-examples, is: instead of serve_forever(), keep serving as long as a condition is met, with the server checking the condition before and after each request. For example:
import CGIHTTPServerimport BaseHTTPServerKEEP_RUNNING = Truedef keep_running(): return KEEP_RUNNINGclass Handler(CGIHTTPServer.CGIHTTPRequestHandler): cgi_directories = ["/cgi-bin"]httpd = BaseHTTPServer.HTTPServer(("", 8000), Handler)while keep_running(): httpd.handle_request()
In my python 2.6 installation, I can call it on the underlying TCPServer - it still there inside your HTTPServer
:
TCPServer.shutdown>>> import BaseHTTPServer>>> h=BaseHTTPServer.HTTPServer(('',5555), BaseHTTPServer.BaseHTTPRequestHandler)>>> h.shutdown<bound method HTTPServer.shutdown of <BaseHTTPServer.HTTPServer instance at 0x0100D800>>>>>