在Django中请求间共享对象
我正在使用一个Python模块(PyCLIPS)和Django 1.3。
我想开发一个线程安全的类,这个类要实现对象池和单例模式,并且在Django的请求之间可以共享。
举个例子,我想做到以下几点:
- 一个请求从对象池中获取一个带有某个ID的对象,处理完这个对象后再把它放回池里,然后发送一个包含对象ID的响应。
- 另一个请求拿着对象的ID,从池中获取这个ID对应的对象,然后重复上面的步骤。
- 但是,对象的状态必须在服务器运行期间保持,即使它在池中。
这应该像Java EE中的单例会话Bean。
我该怎么做呢?有没有什么我应该阅读的资料?
更新: 我不能把池中的对象存储到数据库中,因为这些对象是一个用C语言编写的库的包装器,这个库是专家系统引擎CLIPS的API。
谢谢!
3 个回答
这些是数据库对象吗?如果是的话,数据库本身就像一个池子,没必要做什么特别的事情——每个请求都可以独立地从数据库中加载实例,修改它,然后再保存回去。
在评论后编辑 好吧,最大的问题是,生产环境中的网络服务器通常是多进程的,所以任何全局变量(比如池子)在不同进程之间是不能共享的。你需要把它们存储在一个可以全局访问的地方。虽然不太确定,但它们能用Pickle序列化吗?如果可以的话,也许memcache会有效。
假设这个对象不能被序列化(也就是不能简单地保存成文件),你就需要创建一个应用程序来管理这个对象,以及所有需要对它进行的操作。最简单的做法可能是创建一个单进程的 wsgi 应用(在不同的端口上),这个应用会提供一个接口,让你可以进行所有需要的操作。至于你是选择使用 RESTful 接口还是表单提交,这就看你个人的喜好了。
我觉得这里需要换个角度来看。Django和Java不一样,解决方案应该针对多进程环境,而不是多线程环境。
Django没有直接对应的单例会话对象。
不过,我觉得你的描述完全可以适用于经典的数据库模型。你想保存每个对象的数据,这些数据应该始终存放在数据库层。
另外,你也可以把数据保存在会话中,Django为登录用户和匿名用户都提供了会话功能 - 可以查看Django会话的文档。
如果你尝试使用其他你在Java环境中熟悉的模式,最终可能会失败,因为Java的网络容器和Python/Django的多进程环境之间差别很大。
补充:考虑到这些对象并不是你应用的本地对象,而是通过第三方库访问的,这确实让事情变得复杂。我感觉这些对象不应该由网络层处理,而应该由某种外部服务来处理,这样你就可以在多进程环境中访问它们。正如Daniel提到的,你可以把它们放在缓存中(如果这些对象可以被序列化)。但我觉得这些对象不应该放在网络层。