zc.async的集成包,允许Plone进行异步操作
项目描述
简介
Plone 3 和 4 中允许异步操作的 zc.async 集成包。
仓库
安装
通常您会在 ZEO 环境中运行 plone.app.async,在该环境中,您将有一个或多个执行您主 zope 实例队列中作业的 worker 实例。
为了简化,假设您有一个可以排队新作业的实例,以及一个消费它们的 worker 实例,它们都在单个数据库上操作。在这种情况下,您的 buildout 配置将类似于以下内容
[zeo] recipe = plone.recipe.zope2zeoserver file-storage = ${buildout:directory}/var/filestorage/Data.fs [instance] recipe = plone.recipe.zope2instance eggs = Plone plone.app.async zcml = zcml-additional = <include package="plone.app.async" file="single_db_instance.zcml" /> environment-vars = ZC_ASYNC_UUID ${buildout:directory}/var/instance-uuid.txt [worker] recipe = plone.recipe.zope2instance eggs = ${instance:eggs} zcml = ${instance:zcml} zcml-additional = <include package="plone.app.async" file="single_db_worker.zcml" /> environment-vars = ZC_ASYNC_UUID ${buildout:directory}/var/worker-uuid.txt
这里有两个重要的部分
每个实例都必须设置 ZC_ASYNC_UUID 环境变量,以便正确集成到 zc.async。
每个实例都加载 single_db_instance.zcml 配置。worker 实例加载 single_db_worker.zcml 配置,以便设置队列并将自己配置为调度程序。
有关更多详细信息,请参阅包中包含的 示例 buildout 配置。
Plone 3
使用 zope.app.keyreference
Plone 4
使用 five.intid
致谢
从 Enfold 的 plone.async.core 包中使用的代码已用于设置队列。
参考
zc.async 在 PyPI
plone.async.core Subversion 仓库
用户文档
基本使用
假设您的设置已完成,您可以从以下操作开始获取 AsyncService 实用程序
>>> from zope.component import getUtility >>> from plone.app.async.interfaces import IAsyncService >>> async = getUtility(IAsyncService) >>> async <plone.app.async.service.AsyncService object at ...> >>> folder = layer['test-folder'] >>> portal = layer['portal']
您已经可以获取 zc.async 队列
>>> async.getQueues() <zc.async.queue.Queues object at ...> >>> import zc.async.dispatcher >>> from plone.app.async.testing import _dispatcher_uuid >>> zc.async.dispatcher.get(_dispatcher_uuid) <zc.async.dispatcher.Dispatcher object at ...> >>> queue = async.getQueues()[''] >>> queue <zc.async.queue.Queue object at ...>
让我们定义一个简单的异步执行函数。请注意,第一个参数 必须是 一个有效的 Zope 对象
>>> from plone.app.async.tests.funcs import *
并将它排队
>>> job = async.queueJob(addNumbers, folder, 40, 2) >>> len(queue) 1 >>> job.status u'pending-status'
在实际生活中,作业将由 worker 执行。在测试中,我们需要提交以便调度程序意识到作业并执行它。此外,我们在作业完成之前继续测试
>>> import transaction >>> from zc.async.testing import wait_for_result >>> transaction.commit() >>> wait_for_result(job) 42
工作批处理
现在让我们尝试一些创建持久对象的作业。首先定义要异步执行的作业
>>> from Products.CMFCore.utils import getToolByName
排队一个创建文档的作业,另一个提交它
>>> job = async.queueJob(createDocument, folder, ... 'foo', 'title', 'description', 'body') >>> job2 = async.queueJob(submitObject, folder, 'foo') >>> transaction.commit()
由于默认情况下作业是按顺序执行的,默认配额设置为 1(即一次只能执行一个作业),因此作业是按提交顺序串行执行的。因此,等待提交作业意味着创建它的作业已经执行
>>> wait_for_result(job2) >>> wt = getToolByName(folder, 'portal_workflow') >>> doc = folder['foo'] >>> wt.getInfoFor(doc, 'review_state') 'pending'
您还可以使用 queueSerialJobs 使用户队列的作业按顺序作为单个作业执行
>>> from plone.app.async.service import makeJob >>> job = async.queueSerialJobs( ... makeJob(createDocument, folder, ... 'bar', 'title', 'description', 'body'), ... makeJob(submitObject, folder, 'bar')) >>> transaction.commit() >>> res = wait_for_result(job) >>> res[0].result 'bar' >>> res[1].status u'completed-status' >>> doc = folder['bar'] >>> wt.getInfoFor(doc, 'review_state') 'pending'
如果您想并行执行作业,可以使用 queueParallelJobs。
安全和用户权限
当一个作业被某个用户排队时,它也会由同一个用户执行,具有相同的角色和权限。因此,例如
>>> job = async.queueJob(createDocument, portal, ... 'foo', 'title', 'description', 'body') >>> transaction.commit()
将失败,因为用户不允许在 Plone 根目录中创建内容
>>> wait_for_result(job) <...Unauthorized...
处理失败和成功
如果您需要处理作业的结果或处理失败,可以通过添加回调来实现。例如
>>> from plone.app.async.tests import funcs >>> job = async.queueJob(addNumbers, folder, 40, 2) >>> c = job.addCallback(job_success_callback) >>> transaction.commit() >>> r = wait_for_result(job) >>> funcs.results ['Success: 42']
可以使用相同的方式处理失败
>>> job = async.queueJob(failingJob, folder) >>> c = job.addCallbacks(failure=job_failure_callback) >>> transaction.commit() >>> r = wait_for_result(job) >>> funcs.results [...RuntimeError...
也可以通过订阅相应的事件来处理所有成功/失败的任务(例如,如果你希望在失败时发送电子邮件)。
>>> from zope.component import provideHandler >>> from plone.app.async.interfaces import IJobSuccess, IJobFailure >>> provideHandler(successHandler, [IJobSuccess]) >>> provideHandler(failureHandler, [IJobFailure]) >>> funcs.results = [] >>> job1 = async.queueJob(addNumbers, folder, 40, 2) >>> job2 = async.queueJob(failingJob, folder) >>> transaction.commit() >>> r = wait_for_result(job2) >>> funcs.results [42, ...RuntimeError...FooBared...
让我们清理并注销成功/失败的处理程序...
>>> from zope.component import getGlobalSiteManager >>> gsm = getGlobalSiteManager() >>> _ = gsm.unregisterHandler(successHandler, [IJobSuccess]) >>> _ = gsm.unregisterHandler(failureHandler, [IJobFailure]) >>> transaction.commit()
变更日志
1.7(未发布)
添加 zope.minmax 依赖项 [vangheem]
1.4 (2012-10-09)
修复测试,以及主要用于 plone.app.async 测试层消费者的辅助工具 [kiorky]
修复 rst 标记 [kiorky]
1.3 (2012-10-05)
buildout 基础设施刷新 [kiorky]
plone 4.3 兼容性 [kiorky]
将测试从 collective.testcaselayer 切换到 plone.app.testing [kiorky]
将 UI 和作业的实验性工作合并回 master [kiorky]
将 plone UI 添加到查看作业 [davisagli]
添加对队列/延迟任务的支持。[kiork,davisagli,do3cc]
1.2 - 2012-04-26
修复包含以正确与 dexterity 和 simplejson 一起使用 [vangheem]
更改 ping 间隔以更合理,以便在重启后,你的工作器不需要太长时间才能重新上线。 [vangheem]
1.1 - 2011-07-21
添加 MANIFEST.in. [WouterVH]
更改 zcml:condition 以使用 plone-4 功能,针对 zope.(app.)keyreference [vangheem]
始终在测试层中使用 loadZCMLFile 以防止 Zope 2.13 中断。 [stefan]
通过增加调度器 ping 间隔来避免过度的 ZODB 增长。https://mail.zope.org/pipermail/zope-dev/2011-June/043146.html [stefan]
1.0 - 2011-01-03
条件包含 zope.app.keyreference ZCML。 [vangheem]
修复由匿名用户启动的异步作业。 [naro]
添加完整的示例 buildouts. [stefan]
在 Plone 3 和 4 下使测试通过。由于某些奇怪的原因,异常表示已更改。 [stefan]
1.0a6 - 2010-10-14
第一个公共版本。 [ggozad]
1.0a5 - 2010-10-14
而不是猜测用户 ID 可能来自哪里,记录用户文件夹的路径,并使用该路径恢复用户。[mj]
1.0a4 - 2010-09-09
在测试中使用多数据库设置以保持 testcaselayer 正常工作。[stefan, ggozad]
1.0a3 - 2010-09-01
将辅助函数与测试设置分开,以便可以在非测试代码中使用。[witsch]
1.0a2 - 2010-08-30
为单/多和实例/工作器创建单独的 zcml 配置。[stefan, ggozad]
1.0a1 - 2010-08-25
为 Plone 提供 zc.async 集成。初始发布。[ggozad, stefan]
项目详情
plone.app.async-1.7.0.zip 的散列
算法 | 散列摘要 | |
---|---|---|
SHA256 | dadbc2f9e9679126788875772e78be24cb1e1a296d126b89570476d3ae15b07a |
|
MD5 | 44fdfaccbea9fad8a4e56a5c1bfdf04d |
|
BLAKE2b-256 | ac5f17b0cb74f0444179dc18f8b20c2fc3b43e70dc6aff46064272ca5fb9a024 |