python r flask rserve pyrserve

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.