我们需要一些公共位置为每个用户创建一个rserve连接。最简单的方法是将multiprocessing.Manager
作为单独的进程运行。启动您的应用程序,以便管理人员将可前
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()
运行:
python rserve_manager.py
我们可以用一个简单的函数请求时从应用程序访问该管理器。这假设你已经在会话中获得了“user_id”的值(例如,Flask-Login会这样做)。这最终使得每个用户的rserve连接是唯一的,而不是每个会话。
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一起工作。
为什么你需要为一个会话使用相同的连接? – dirn 2015-02-10 02:40:09
因为我需要R名称空间中的对象在会话期间为同一用户保留(但对其他用户不可见/可访问)。例如,用户可以加载一些数据并适合模型 - 我希望能够在其他页面上访问该模型(不需要重新设置)(即在其他页面发出请求之后)。 – izyda 2015-02-10 05:39:21
我明白了。我不确定我真的需要每个用户都有一个可重用的连接。我唯一的要求是用户的R连接/会话能够访问使用该用户先前请求创建的R对象。我想一个可行的解决方案可能是有一个R连接将当前R工作区保存到服务器,将该工作区的ID保存为一个cookie,并且在新的请求时,有一个新的R连接读取该工作区返回... – izyda 2015-02-10 06:35:45