python - Almacenar datos grandes o una conexión de servicio por sesión de Flask
rserve pyrserve (1)
Estoy escribiendo una pequeña aplicación Flask y estoy haciendo que se conecte a Rserve usando pyRserve. Quiero que cada sesión se inicie y luego mantenga su propia conexión Rserve.
Algo como esto:
session[''my_connection''] = pyRserve.connect()
no funciona porque el objeto de conexión no es serializable JSON. Por otro lado, algo como esto:
flask.g.my_connection = pyRserve.connect()
no funciona porque no persiste entre solicitudes. Para agregar a la dificultad, no parece que pyRserve proporcione ningún identificador para una conexión, por lo que no puedo almacenar una ID de conexión en la sesión y usarla para recuperar la conexión correcta antes de cada solicitud.
¿Hay alguna manera de lograr tener una conexión única por sesión?
Lo siguiente se aplica a cualquier dato global de Python que no desee volver a crear para cada solicitud, no solo rserve, y no solo datos que sean únicos para cada usuario.
Necesitamos una ubicación común para crear una conexión rserve para cada usuario.
La forma más sencilla de hacer esto es ejecutar un
multiprocessing.Manager
como un proceso separado.
import atexit
from multiprocessing import Lock
from multiprocessing.managers import BaseManager
import pyRserve
connections = {}
lock = Lock()
def get_connection(user_id):
with lock:
if user_id not in connections:
connections[user_id] = pyRserve.connect()
return connections[user_id]
@atexit.register
def close_connections():
for connection in connections.values():
connection.close()
manager = BaseManager(('''', 37844), b''password'')
manager.register(''get_connection'', get_connection)
server = manager.get_server()
server.serve_forever()
Ejecútelo antes de iniciar su aplicación, para que el administrador esté disponible:
python rserve_manager.py
Podemos acceder a este administrador desde la aplicación durante las solicitudes utilizando una función simple. Esto supone que tiene un valor para "user_id" en la sesión (que es lo que haría Flask-Login, por ejemplo). Esto termina haciendo que la conexión de rserve sea única por usuario, no por sesión.
from multiprocessing.managers import BaseManager
from flask import g, session
def get_rserve():
if not hasattr(g, ''rserve''):
manager = BaseManager(('''', 37844), b''password'')
manager.register(''get_connection'')
manager.connect()
g.rserve = manager.get_connection(session[''user_id''])
return g.rserve
Acceda a él dentro de una vista:
result = get_rserve().eval(''3 + 5'')
Esto debería ayudarlo a comenzar, aunque hay muchas cosas que se pueden mejorar, como no codificar la dirección y la contraseña, y no tirar las conexiones al administrador. Esto fue escrito con Python 3, pero debería funcionar con Python 2.