我正在lighttpd后面开发一个CherryPy FastCGI服务器,其设置如下,以支持在CherryPy控制器内使用ORM SQLAlchemy会话。然而,当我用大约500个循环的14个并发请求运行压力测试时,它会在一段时间后开始给出诸如open_dbsession()
中的AttributeError: '_ThreadData' object has no attribute 'scoped_session_class'
或{
只有在lighttpd后面运行服务器时才会发生这种情况,而不是直接通过cherrypy.engine.start()
运行服务器。已确认connect()
没有引发异常。在
我还尝试将scoped_session
的返回值赋给GlobalSession
(就像它是here),但是它给出了像UnboundExceptionError
这样的错误和其他SA级错误。(并发:10,循环:1000,错误率:16%。即使直接运行时也发生。)
有一些可能的原因,但我缺乏足够的知识来选择一个。
1在FastCGI环境下,start_thread
订阅是否不可靠?似乎open_dbsession()
是在connect()
之前调用的
2cherrypy.thread_data
是否因某种原因被清除?在
import sqlalchemy as sa
from sqlalchemy.orm import session_maker, scoped_session
engine = sa.create_engine(dburi, strategy="threadlocal")
GlobalSession = session_maker(bind=engine, transactional=False)
def connect(thread_index):
cherrypy.thread_data.scoped_session_class = scoped_session(GlobalSession)
def open_dbsession():
cherrypy.request.scoped_session_class = cherrypy.thread_data.scoped_session_class
def close_dbsession():
cherrypy.request.scoped_session_class.remove()
cherrypy.tools.dbsession_open = cherrypy.Tool('on_start_resource', open_dbsession)
cherrypy.tools.dbsession_close = cherrypy.Tool('on_end_resource', close_dbsession)
cherrypy.engine.subscribe('start_thread', connect)
thread_index
参数(感谢注释)
如果没有显式实例化作用域的\u session类,则不会发生此错误。在
即
如果您查看
plugins.ThreadManager.acquire_thread
,您将看到self.bus.publish('start_thread', i)
,其中i
是所见线程的数组索引。订阅start_thread
通道的任何侦听器都需要接受该i
值作为位置参数。所以重写connect函数如下:def connect(i):
我想它是在默默地失败;我会看看我是否能找到它,测试并修复它。在
相关问题 更多 >
编程相关推荐