servidor - Comprender la persistencia global de objetos en las aplicaciones Python WSGI
servidor web con python (3)
En el caso de su primera pregunta, creo que podría considerar la función webapp2.Request.registry . Es un dict para almacenar instancias que diferentes módulos pueden compartir durante la vida de la solicitud.
Por otro lado, también es útil el webapp2.WSGIApplication.registry . En este caso, las instancias persisten entre las solicitudes y se pueden compartir (y reutilizar) para lo que su aplicación necesite durante la vida de su aplicación, evitando crear instancias en el alcance global.
Considere el siguiente código en mi aplicación WebApp2 en Google App Engine:
count = 0
class MyHandler(webapp2.RequestHandler):
def get(self):
global count
count = count + 1
print count
Con cada actualización de la página, el recuento aumenta más.
Vengo del mundo de PHP donde cada solicitud era un nuevo entorno global. Lo que entiendo que está sucediendo aquí es que, debido a que estoy usando la configuración de wsgi para WebApp2, Python no inicia un nuevo proceso en cada solicitud. Si estuviera usando una configuración cgi, por otro lado, el entorno global volvería a crear instancias cada vez, como PHP ...
Suponiendo que lo anterior es correcto (si no, corrígeme) ...
- ¿Cómo podría manejar los escenarios donde quisiera una variable global que persistiera solo durante el tiempo de vida de la solicitud? Podría poner una variable de instancia en la clase RequestHandler, pero ¿qué ocurre con los módulos de utilidad que importo que usan variables globales para cosas como almacenar un objeto de mensaje?
- ¿Hay algún tipo de técnica para restablecer todas las variables o forzar una nueva instanciación del entorno?
- ¿El entorno global persiste indefinidamente o se restablece en algún momento?
- ¿Alguno de estos GAE es específico o la persistencia global de wsgi funciona de la misma forma en cualquier escenario de servidor?
EDITAR:
Aquí hay un intento de usar threadlocal:
count = 0
mydata = threading.local()
mydata.count = 0
class MyHandler(webapp2.RequestHandler):
def get(self):
global count
count = count + 1
print count
mydata.count = mydata.count + 1
print mydata.count
Estos también aumentan en las solicitudes
Su análisis de la situación es correcto, una aplicación web de Python es un proceso de larga duración. Lleva mucho tiempo activar el intérprete de Python y no se completa cada solicitud.
Es completamente posible crear una variable global que sea diferente "por solicitud". Esto se hace en muchos marcos y a la gente parece gustarle. La forma de hacer esto depende del servidor. La mayoría de los servidores usan "un hilo por solicitud", y creo que GAE también lo hace. Si este es el caso, puede usar una variable hilocal . Si le preocupa que este valor permanezca entre las solicitudes de ese hilo, necesitará algún código de gestión que pueda engancharse al inicio / finalización de una solicitud. El middleware WSGI es un buen lugar para esto si el framework WebApp2 no proporciona una buena manera de hacerlo.
Es solo Python, y una solicitud se sirve en su propio hilo. Desde allí puedes hacer lo que quieras. No hay nada en Python que simplemente reinicie todas las variables globales, y generalmente no hay garantía (especialmente con GAE) de que el proceso que sirve su solicitud sea el mismo proceso cada vez, lo que significa que sus globales no deben usarse para persistir datos entre solicitudes a menos que realmente sé lo que estás haciendo.
Hay muchos frameworks que proporcionan un buen soporte para hacer esto ya, así que si WebApp2 no lo hace, entonces sugeriría buscar en otro lado. Python tiene muchas opciones y muchas de ellas se ejecutan en GAE.
Su comprensión es correcta. Si desea que las variables persistan durante la duración de la solicitud, no debe convertirlas en globales, conviértalas en variables de instancia en su clase RequestHandler, a las que se accede como self.var
. Como se crea una instancia de un nuevo RequestHandler para cada solicitud, sus variables se mantendrán exactamente el tiempo que lo necesite. Es mejor evitar las variables globales a menos que realmente necesite un alcance global (en lugar de específico de la solicitud).
También tenga en cuenta que su aplicación de App Engine se ejecutará en varios servidores; los globales solo son accesibles a las solicitudes dentro del mismo servidor.