2011-04-04 86 views
3

我正在金字塔框架上构建一个应用程序,并希望与它一起使用web2py-DAL。 Firebird嵌入是选择的数据库。独立web2py-DAL与金字塔 - 请求,线程和内存

这很好,直到我试图从一个网页异步调用多个视图。像“无效光标状态”,“无效光标引用”或“尝试重新关闭已关闭的光标”是从kinterbasdb驱动程序来的,sqlite只是在没有任何错误消息的情况下发生故障并使用python。这些视图可调用函数除了通过SELECTing进行简单的读取之外什么也不做。

这种情况发生在金字塔根工厂返回与每个请求相同的DAL对象的情况下。似乎线程形式不同的请求正在使用同一个游标对象,所以游标被关闭,而另一个线程则假定游标在这里。

如果我在每个请求上创建一个新的DAL对象,我会遇到另一个问题 - 每个请求上的每个新连接都会分配内存,并且此内存不会被释放。所以在一些docents请求之后,有几百MB浪费的内存。

不幸的是,Sqlalchemy不适合这个项目。

有什么想法吗?

+0

为什么你不在这个网络环境中使用完整的服务器版本?嵌入意味着它将在进程中运行,每一个都可独占访问数据库。恕我直言,这解释了为什么一切正常,直到两个不同的请求强制服务器试图同时打开数据库。如果第二个请求来自不同的客户端,而服务器仍在处理第一个请求,则会发生同样的情况。 – jachguate 2011-04-04 17:43:52

+0

你最好直接在web2py邮件列表中询问这个问题。 – 2011-04-04 23:11:46

+0

@jachguate 问题不是火鸟 - 如果我使用服务器版本,所有的问题仍然存在。我发现DAL对象不能在线程之间共享。我可以在每个线程的开始创建一个新的DAL对象,然后关闭它。现在的问题 - 金字塔请求线程在哪里结束?哪里是删除DAL对象的正确位置?另一个选择是为db请求构建一个堆栈,然后将db请求从单个线程传递给DAL对象... @ Graham-Dumpleton 对。或金字塔。如果它在那里,我会在这里发布我的解决方案。 – 2011-04-05 10:51:21

回答

2

问题是应该在每个请求上创建DAL对象。但之后必须手动关闭。

我做了那样:有请求对象的

request.add_finished_callback 

属性,所以我扩展以这种方式的DAL对象:

class Root(DAL): 
    def __init__(self, request, uri): 
     DAL.__init__(self, uri, pool_size=0) 
     request.add_finished_callback(self._close) 

    def _close(self, request): 
     self._adapter.close_all_instances('commit') 

一个新的根对象是然后在每个请求上由root_factory返回。

感谢web2py-users组!

1

Some solutions from web2py mailing list。

+0

是的!我在几个小时前发布了这个问题,现在已经有了非常有用的方法。 web2py用户组是伟大的。 – 2011-04-06 18:04:08