在使用Plone 4时,我已成功创建订阅者事件,以便在保存自定义内容类型时执行额外处理。这是通过使用Products.Archetypes.interfaces.IObjectInitializedEvent
接口完成的。
configure.zcml中
<subscriber
for="mycustom.product.interfaces.IRepositoryItem
Products.Archetypes.interfaces.IObjectInitializedEvent"
handler=".subscribers.notifyCreatedRepositoryItem"
/>
subscribers.py
def notifyCreatedRepositoryItem(repositoryitem, event):
"""
This gets called on IObjectInitializedEvent - which occurs when a new object is created.
"""
my custom processing goes here. Should be asynchronous
然而,额外的处理有时需要太长时间,我想知道是否有办法在后台运行它,即异步。
是否可以异步运行订阅者事件,例如在保存对象时?
答案 0 :(得分:6)
没有开箱即用。您需要为您的环境添加异步支持。
看看plone.app.async
;你需要一个ZEO环境和至少一个额外的实例。后者将运行从您的站点进入队列的异步作业。
然后,您可以定义要异步执行的方法,并将任务推送到队列中,以异步方式执行此类方法。
示例代码,将任务推入队列:
from plone.app.async.interfaces import IAsyncService
async = getUtility(IAsyncService)
async.queueJob(an_async_task, someobject, arg1_value, arg2_value)
和任务本身:
def an_async_task(someobject, arg1, arg2):
# do something with someobject
其中someobject
是ZODB中的持久对象。 IAsyncService.queueJob
至少使用 函数和上下文对象,但您可以根据需要添加任意数量的参数来执行任务。参数必须是可选择的。
该任务将在当前请求的上下文之外由异步工作器实例执行。
答案 1 :(得分:1)
为了提供更多选项,您可以尝试collective.taskqueue,非常简单且非常强大(并避免plone.app.async的一些缺点)。
关于PyPI的描述已足以让你立刻加快速度,你可以使用redis进行队列管理,这是一个很大的优势。