import socket
import time
import signal
+import asyncore
-from ganeti import constants
-from ganeti import serializer
-from ganeti import utils
from ganeti import http
"""
return self.error_message_format % values
-class HttpServer(http.HttpBase):
+class HttpServer(http.HttpBase, asyncore.dispatcher):
"""Generic HTTP server class
Users of this class must subclass it and override the HandleRequest function.
"""
http.HttpBase.__init__(self)
+ asyncore.dispatcher.__init__(self)
if request_executor_class is None:
self.request_executor = HttpServerRequestExecutor
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self._children = []
-
- mainloop.RegisterIO(self, self.socket.fileno(), select.POLLIN)
+ self.set_socket(self.socket)
+ self.accepting = True
mainloop.RegisterSignal(self)
def Start(self):
def Stop(self):
self.socket.close()
- def OnIO(self, fd, condition):
- if condition & select.POLLIN:
- self._IncomingConnection()
+ def handle_accept(self):
+ self._IncomingConnection()
def OnSignal(self, signum):
if signum == signal.SIGCHLD:
# As soon as too many children run, we'll not respond to new
# requests. The real solution would be to add a timeout for children
# and killing them after some time.
- pid, status = os.waitpid(0, 0)
+ pid, _ = os.waitpid(0, 0)
except os.error:
pid = None
if pid and pid in self._children:
if pid == 0:
# Child process
try:
+ # The client shouldn't keep the listening socket open. If the parent
+ # process is restarted, it would fail when there's already something
+ # listening (in this case its own child from a previous run) on the
+ # same port.
+ try:
+ self.socket.close()
+ except socket.error:
+ pass
+ self.socket = None
+
self.request_executor(self, connection, client_addr)
except Exception:
logging.exception("Error while handling request from %s:%s",
def PreHandleRequest(self, req):
"""Called before handling a request.
- Can be overriden by a subclass.
+ Can be overridden by a subclass.
"""
def HandleRequest(self, req):
"""Handles a request.
- Must be overriden by subclass.
+ Must be overridden by subclass.
"""
raise NotImplementedError()