基于Asyncore的Plone异步任务队列
项目描述
collective.taskqueue
collective.taskqueue通过提供一个用于异步排队请求到ZPublisher的小型框架,使Plone插件能够启用异步任务。使用这种方法,异步任务只是对通常注册的浏览器视图(或其他可遍历的可调用对象)的正常调用,并且它们像所有其他请求一样使用PAS进行身份验证。
此外,可以配置视图,使它们仅对异步请求可见。此外,collective.taskqueue附带一个特殊的PAS插件,该插件将每个请求的身份验证为队列它的用户。
最小配置
zope-conf-additional =
%import collective.taskqueue
<taskqueue />
<taskqueue-server />
最小配置为您提供单个可变实例局部队列和消费者,但无交付保证。
具有多个队列的最小配置
zope-conf-additional =
%import collective.taskqueue
<taskqueue />
<taskqueue-server />
<taskqueue>
queue mailhost
</taskqueue>
<taskqueue-server>
queue mailhost
</taskqueue-server>
推荐使用Redis的最小配置
eggs =
collective.taskqueue [redis]
zope-conf-additional =
%import collective.taskqueue
<taskqueue>
type redis
unix_socket_path ${buildout:directory}/var/redis.sock
</taskqueue>
<taskqueue-server>
name ${:_buildout_section_name_}
</taskqueue-server>
Redis支持为您提供可分发的队列,这些队列可以在实例之间共享。所有实例都应该有特定于队列的<taskqueue />,但只有消费实例需要<taskqueue-server />。
具有多个队列的示例Redis配置
eggs =
collective.taskqueue [redis]
zope-conf-additional =
%import collective.taskqueue
<taskqueue>
type redis
unix_socket_path ${buildout:directory}/var/redis.sock
</taskqueue>
<taskqueue-server>
name ${:_buildout_section_name_}
</taskqueue-server>
<taskqueue>
type redis
queue mailhost
unix_socket_path ${buildout:directory}/var/redis.sock
</taskqueue>
<taskqueue-server>
queue mailhost
name ${:_buildout_section_name_}
</taskqueue-server>
建议仅使用本地Redis安装,因为远程连接可能会被防火墙杀死(没有ping或心跳来通过企业防火墙保持连接活跃)。
排队任务
from collective.taskqueue import taskqueue
task_id = taskqueue.add('/Plone/path/to/my/view')
任务在成功交易后会被排队(并消费)。
为了使视图只对异步请求可见,可以将视图注册到特殊层 collective.taskqueue.interfaces.ITaskQueueLayer,该层只存在于由 collective.taskqueue 分发的请求中。
默认情况下,taskqueue.add 会将当前请求的头部复制到异步请求中。这应该足以以与当前请求相同的方式认证请求。
taskqueue.add 返回一个类似于 id 的 uuid 作为任务的标识符,这可以用于跟踪任务状态。任务标识符随后作为 X-Task-Id 头部在排队请求中提供。您可以在任务视图中通过 self.request.getHeader('X-Task-Id') 获取它。
可以通过自定义 PAS 插件实现更健壮的认证。collective.taskqueue 随附一个可选安装的 PAS 插件,该插件将每个请求认证为排队用户。为了实现这一点,collective.taskqueue 将 X-Task-User-Id 头部附加到排队请求中。
Taskqueue API 吸收了 Google AppEngine Task Queue API 的灵感。
检查队列
作为 Plone 的最小化异步框架,collective.taskqueue 不提供任何用于观察或检查队列的用户界面。然而,从受信任的 Python 中,可以查找命名队列的当前长度(默认队列的名称是“default”)
from zope.component import getUtility
from collective.taskqueue.interfaces import ITaskQueue
len(getUtility(ITaskQueue, name='default'))
高级配置
支持的 <taskqueue /> 设置包括
- queue (默认=default)
唯一的任务队列名称。
- type (默认=local)
任务队列类型('local' 或 'redis')或自定义类型的完整类路径。
- unix_socket_path
Redis 服务器 unix 套接字路径(使用 host 和 port 代替)。
其他支持的 Redis-queue 选项包括:host、port、db 和 password。
支持的 <taskqueue-server /> 设置包括
- name (默认=default)
消费者名称,最好使用实例名称。消费者是 Redis-queues 用于从队列中保留消息以实现保证交付的名称。
- queue (默认=default)
此消费者的队列名称(消费服务器)。必须注册一个具有匹配 queue 值的 <taskqueue/>。
- concurrent_limit (默认=1)
此消费者的最大并发任务限制。建议将其设置得小于 zserver-thread-count。将此设置为默认值(1)应在最小化 ConflictErrors 方面提供最佳结果。
- retry_max_count (默认=10)
由此消费者分发的请求的最大 ZPublisher 重试次数。
高级用法
taskqueue.add 接受以下参数(带有 default 值)
- url (必需,无默认值)
表示要调用的任务的目标路径。
- method (可选,默认=GET)
调用使用的 HTTP 方法。必须是 GET 或 POST。
- params (可选,默认=None)
一个可选任务参数的字典,这些参数作为查询字符串附加到给定的 url 后面。
- headers (可选,默认=None)
一个可选 HTTP 头部字典,用于附加到(或用于替换)从活动请求中复制的头部。
- payload (可选,默认=current)
为 POST 请求的 optional 负载。默认情况下,将从活动请求中复制负载。使用 payload=None 可以防止复制活动负载。
- queue (可选,默认=按注册顺序字母第一的队列)
当注册了多个队列时,可选的队列名称。
Redis 队列工作原理
taskqueue.add 准备一条消息,该消息将在事务结束时被推入键 collective.taskqueue.%(queue)s(其中 %(queue)s 是队列名称)中。如果在事务投票期间 Redis 连接断开,则整个事务将被中止。
<taskqueue-server /> 从队列中读取每条消息(rpoplpush),使它们保留在键 collective.taskqueue.%(queue)s.%(name)s(其中 %(name)s 是 <taskqueue-server/> 的名称)中,直到每个异步处理请求返回 HTTP 响应。
在启动时,以及当所有已知消息都已处理完毕时,<taskqueue-server/> 将 collective.taskqueue.%(queue)s.%(name)s 清空到 collective.taskqueue.%(queue)s(使用 rpoplpush)中,并再次处理这些任务。(例如,如果 Plone 在处理任务请求的中间被迫重启。)
Redis 集成使用 PubSub 通知自身关于队列中新的消息(并在 Plone 的 asyncore-loop 方面尽可能即时处理)。
变更日志
1.0 (2020-02-10)
添加对 Plone 5.2 的支持 [gforcada]
修复使用 @implementer 装饰器 [petschki]
0.8.2 (2017-01-03)
修复在任务创建时由于获取了 bool 头部值而导致错误的问题 [datakurre]
0.8.1 (2017-01-02)
修复由于原始请求中的空负载而导致使用 POST 方法从 GET 方法创建的任务队列请求失败的问题 [datakurre]
0.8.0 (2015-12-13)
添加对 Plone 5 的支持 [datakurre]
修复无法为带有查询字符串的 URL 添加附加参数的问题 [datakurre]
0.7.1 (2015-01-26)
修复冲突事务的问题:只有在事务成功完成后才入队任务。 [jone]
0.7.0 (2014-12-29)
将 NoRollbackSavepoint 替换为支持回滚的 DummySavepoint [datakurre]
0.6.2 (2014-12-19)
添加最小 savepoint 支持,使用 NoRollbackSavepoint [datakurre]
0.6.1 (2014-08-05)
修复由于请求不是 HTTPRequest,而是仅继承它,因此未设置任务队列请求的语言绑定的问题 [datakurre]
0.6.0 (2014-05-19)
将 taskqueue.add 添加到返回任务 ID,该 ID 与请求.getHeader(‘X-Task-Id’) 后匹配 [datakurre]
0.5.1 (2014-05-14)
修复由于未捕获的异常而未释放并发任务计数器互斥锁的问题 [datakurre]
修复在 asyncore.poll 期间在 asyncore.map 中关闭套接字的问题 [datakurre]
0.5.0 (2014-04-03)
修复与当前活动 Redis 任务重新入队(并多次处理)相关的线程和执行顺序问题 [datakurre]
添加“X-Task-Id”头部以帮助跟踪消费视图中的任务 [datakurre]
0.4.4 (2013-11-25)
修复意外总是需要 redis+msgpack 的回归 [datakurre]
更新文档 [Dylan Jay]
修复默认的‘unix_socket_path’ [fixes #8] [Dylan Jay]
0.4.3 (2013-11-15)
更新 README [datakurre]
0.4.2 (2013-11-15)
更新 README [datakurre]
0.4.1 (2013-11-14)
更新 README [datakurre]
0.4.0 (2013-11-14)
通过用 <taskqueue/>-component 替换显式实用程序和 <product-configuration/> 重新构建配置 [datakurre]
0.3.1 (2013-11-13)
通过第一个接受测试增强接受测试支持 [datakurre]
0.3.0 (2013-11-10)
修复 TaskQueueServer 在 Redis 重启后重新连接到 Redis [datakurre]
仅在开发模式下在 Zope 启动时 ping Redis [datakurre]
添加可选的任务队列 PAS 插件,以独立验证队列任务为其创建者 [datakurre]
0.2.2 (2013-11-09)
修复仅在队列被清空时刷新 Redis pub-通知的问题,以确保所有消息都将被处理 [datakurre]
0.2.1 (2013-11-09)
修复任务队列套接字默认不可读的问题 [datakurre]
0.2.0 (2013-11-09)
增强Redis集成,将Redis通知pubsub套接字直接连接到异步处理即时消息[datakurre]
修复要求redis >= 2.4.10 [修复 #2] [datakurre]
修复在明显打算使用RedisTaskQueues而无需redis依赖项时不会启动的错误。也无法连接到Redis时崩溃。[修复 #1] [datakurre]
0.1.0 (2013-11-03)
用于实验用途的第一个版本。
项目详情
集体任务队列-1.0.tar.gz的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 96354a49ed6cd5eb622fdb4671e4973eeb0bf40c9f23923722f1d06e5b5ade7a |
|
MD5 | b0653576bc221d120183f3b97f800892 |
|
BLAKE2b-256 | c047fba12e93691e852e2f0b8dc5e421bf6c9b1f9c5b97f2911d8d9288cc8a94 |
集体任务队列-1.0-py2-none-any.whl的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | bfb52695c031dfc1d61e1a946515cb4efefdc7000cdeb63ca790522197e114aa |
|
MD5 | 562a4afb8e6504667f2e2b4c4715871a |
|
BLAKE2b-256 | eace50de73362ec7fc295686f230df61e3b9ffb74b8521d1381cccc70ca53140 |