在Flask会话中存储大数据或服务连接 [英] Store large data or a service connection per Flask session

查看:183
本文介绍了在Flask会话中存储大数据或服务连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个小的Flask应用程序,并使用pyRserve将其连接到Rserve.我希望每个会话都可以启动,然后维护自己的Rserve连接.

I'm writing a small Flask application and am having it connect to Rserve using pyRserve. I want every session to initiate and then maintain its own Rserve connection.

类似这样的东西:

session['my_connection'] = pyRserve.connect()

不起作用,因为连接对象不可JSON序列化.另一方面,是这样的:

doesn't work because the connection object is not JSON serializable. On the other hand, something like this:

flask.g.my_connection = pyRserve.connect()

不起作用,因为它在两次请求之间不存在.更麻烦的是,pyRserve似乎并没有为连接提供任何标识符,因此我无法在会话中存储连接ID,并无法在每次请求之前使用该ID检索正确的连接.

doesn't work because it does not persist between requests. To add to the difficulty, it doesn't seem as though pyRserve provides any identifier for a connection, so I can't store a connection ID in the session and use that to retrieve the right connection before each request.

是否有一种方法可以使每个会话具有唯一的连接?

Is there a way to accomplish having a unique connection per session?

推荐答案

以下内容适用于您不想为每个请求重新创建的任何全局Python数据,不仅适用于保留,而且不仅适用于每个请求的唯一数据用户.

The following applies to any global Python data that you don't want to recreate for each request, not just rserve, and not just data that is unique to each user.

我们需要一些公共的位置来为每个用户创建一个保留连接.最简单的方法是将 multiprocessing.Manager 作为单独的过程.

We need some common location to create an rserve connection for each user. The simplest way to do this is to run a multiprocessing.Manager as a separate process.

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()

在启动应用程序之前运行它,以便管理器可用:

Run it before starting your application, so that the manager will be available:

python rserve_manager.py


在请求过程中,我们可以使用简单的功能从该应用访问该经理.假设您在会话中具有"user_id"的值(例如Flask-Login会执行的操作).这样最终使每个用户(而不是每个会话)的保留连接都是唯一的.


We can access this manager from the app during requests using a simple function. This assumes you've got a value for "user_id" in the session (which is what Flask-Login would do, for example). This ends up making the rserve connection unique per user, not per session.

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

在视图中访问它:

result = get_rserve().eval('3 + 5')


这应该使您入门,尽管还有很多可以改进的地方,例如不对地址和密码进行硬编码,以及不丢弃与管理器的连接.这是用Python 3编写的,但应该可用于Python 2.


This should get you started, although there's plenty that can be improved, such as not hard-coding the address and password, and not throwing away the connections to the manager. This was written with Python 3, but should work with Python 2.

这篇关于在Flask会话中存储大数据或服务连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆