1

When I'm threading the SocketServer instance (the serve_forever method) I can quit it easily when sending the text "shutdown", which is what I expect. However, if its not threaded then I run into the issue of it locking up and I can't figure out how to get around this.

The basic flow of the server itself is start->listen->get data->get the command from it->run the command (which is a plugin)->return the results. Here's the code I use:

import SocketServer as SS

NULL_RESP = {"status" : False, "data" : "No data received."}

class ASWCP_Daemon(SS.BaseRequestHandler):
    def handle(self):
        self.data = self.request.recv(1024).strip()

        if self.data == "":
           self.request.sendall(json.dumps(NULL_RESP))
           return None

       tmp = self.data.split(" ", 1)

       cmd = tmp[0]
       args = ""

       try:
           args = str(tmp[1]).split(conf.command_parse)
    except:
           pass

       plugin = plugins["cmd"][cmd]['ref'].init(conf=conf, socket=self)

       try:
           if args[0] == "help":
            self.request.sendall(plugin.help)
       except IndexError:
           status,data = plugin.run(args)
           resp = {"status" : status, "data" : data}
           self.request.sendall(json.dumps(resp))

  if __name__ == "__main__":
   # Log is created here; conf = config file (irrelevant to this issue)

   try:
       if conf.tcp:
           if conf.threaded:
               import threading
               class ThreadedTCPServer(SS.ThreadingMixIn, SS.TCPServer):
                   pass

               server = ThreadedTCPServer((conf.host, conf.listen_port), ASWCP_Daemon)
           else:
               server = SS.TCPServer((conf.host, conf.listen_port), ASWCP_Daemon)
       else:
           server = SS.UDPServer((conf.host, conf.listen_port), ASWCP_Daemon)

       if conf.threaded:
           sthread = threading.Thread(target=server.serve_forever)
           #sthread.daemon = True
           sthread.start()
       else:
           server.serve_forever()
   except KeyboardInterrupt:
       pass

The shutdown plugin's run method is this:

    def run(self, *args, **kwargs):
        if self.socket == None:
            print "> No socket available"
            return (False,"")
        else:
            self.socket.log.info("Shutting down daemon")
            self.socket.server.shutdown()

            return (True,"")

If threaded this is fine, if its not then it gets as far as the self.socket.server.shutdown() method in the plugin. self.socket is the instance of ASWCP_Daemon class.

4

1 回答 1

1
    # Do shutdown() if threaded, else execute server_close()
    if self.sysconf.threaded:
        self.socket.server.shutdown()
    else:
        self.socket.server.server_close()

    return (True,"")

self.sysconf是守护进程的配置(conf在问题的代码中),并且self.socket是对流处理程序的引用。

于 2013-07-12T13:46:10.367 回答