本文介绍了每个 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 并在每次请求之前使用它来检索正确的连接.

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 数据,而不仅仅是 rserve,也不仅仅是每个数据独有的数据用户.

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.

我们需要一些公共位置来为每个用户创建一个 rserve 连接.最简单的方法是运行 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 会做的事情).这最终使 rserve 连接对每个用户都是唯一的,而不是每个会话.


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 会话存储大数据或服务连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-19 01:05