Search code examples
pythonpython-2.7socketssocketserver

How do I modify variables in the SocketServer server instance from within a RequestHandler handler instance in Python?


Here's the code in question:

  class Server(SocketServer.ForkingMixIn, SocketServer.TCPServer):
     __slots__ = ("loaded")

  class Handler(SocketServer.StreamRequestHandler):
     def handle(self):
        print self.server.loaded # Prints "False" at every call, why?
        self.server.loaded = True
        print self.server.loaded # Prints "True" at every call, obvious!

  server = Server(('localhost', port), Handler)
  server.loaded = False

  while True:
     server.handle_request()

Every time a new request comes in, the output I get is False followed by True. What I want is False followed by True the first time, and True followed by True henceforth.

Why aren't the modifications I made to the variable in the server instance persisting outside the scope of the handler's handle() function?

UPDATED:

So, I try using global variables to achieve what I want:

  loaded = False

  class Server(SocketServer.ForkingMixIn, SocketServer.TCPServer):
     pass

  class Handler(SocketServer.StreamRequestHandler):
     def handle(self):
        global loaded
        print loaded # Prints "False" at every call still, why?
        loaded = True
        print loaded # Prints "True" at every call, obvious!

  def main():
     server = Server(('localhost', 4444), Handler)
     global loaded
     loaded = False

     while True:
        server.handle_request()

  if (__name__ == '__main__'):
     main()

And it still doesn't work, i.e. produces the same output as before. Could anyone please tell me where I'm going wrong?


Solution

  • Forking creates a new process, so you can't modify the server's variables in the original process. Try the ThreadingTCPServer instead:

    import SocketServer
    
    class Server(SocketServer.ThreadingTCPServer):
        __slots__ = ("loaded")
    
    class Handler(SocketServer.StreamRequestHandler):
        def handle(self):
            self.server.loaded = not self.server.loaded
            print self.server.loaded # Alternates value at each new request now.
    
    server = Server(('localhost',5000),Handler)
    server.loaded = False
    
    while True:
        server.handle_request()