Como modifico variáveis na instância do servidor SocketServer de dentro de uma instância do manipulador RequestHandler em Python?
-
28-09-2019 - |
Pergunta
Aqui está o código em questão:
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()
Cada vez que chega uma nova solicitação, a saída que recebo é False
seguido pela True
.O que eu quero é False
seguido pela True
pela primeira vez, e True
seguido pela True
daqui em diante.
Por que as modificações que fiz na variável na instância do servidor não persistem fora do escopo do manipulador? handle()
função?
ATUALIZADA:
Então, tento usar variáveis globais para conseguir o que desejo:
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()
E ainda não funciona, ou seja,produz a mesma saída de antes.Alguém poderia me dizer onde estou errando?
Solução
A bifurcação cria um novo processo, portanto você não pode modificar as variáveis do servidor no processo original.Experimente o ThreadingTCPServer:
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()
Outras dicas
Seu problema é que SocketServer.ForkingMixin cria um novo processo para cada solicitação.Portanto, toda vez que uma nova solicitação chega, todas as suas variáveis são redefinidas para seu estado padrão.Então, essencialmente, não importa o que você atribua a self.server.loaded, ele será redefinido na próxima solicitação.É também por isso que os globais não funcionam.
Se você precisa que uma variável persista entre as solicitações, é melhor escrever esses dados em algum lugar mais, er, persistente =).Essencialmente, parece que você está tentando resolver o problema de manter variáveis de sessão.Há um milhão e uma maneiras de fazer isso e dependendo da sua situação, uma forma pode ser mais pertinente que outra.Eu recomendo fortemente observar como outros aplicativos SocketServer baseados em Python fazem isso.
Basta fazer uma rápida pesquisa no Google para obter um código semelhante ao seu:"filetype:py SocketServer ForkingMixIn" (um dos primeiros resultados é CherryPy, que eu recomendo fortemente).