Zope 3的远程任务客户端实用程序
lovely.remotetask的Python项目详细描述
远程任务执行
内容
可爱的远程任务的更改
0.5.2(2010-04-30)
0.5.1(2010-04-14)
0.5(2009-09-10)
2009年5月20日(0.4):
2009年4月5日(0.3):
2008/11/07 0.2.15a1:
2008/02/08 0.2.14:
2008年1月28日(新):
2007年12月??(新):
2007年11月12日0.2.13:
2007年10月28日0.2.12:
2007年10月28日0.2.11:
2007年10月24日0.2.10:
2007/10/08 0.2.9:
2007/10/08 0.2.8:
2007年10月02日0.2.7:
2007/08/07 0.2.6:
2007/08/07 0.2.5:
2007/08/06 0.2.4:
2007年7月26日0.2.3:
2007年7月2日0.2.2:
2007/06/12 0.2.1:
2007/06/12 0.2.0:
内容
此包提供远程任务执行Web服务的实现 它允许在另一台服务器上执行预定义的任务。它也是 可以在特定时间运行cron作业。这些服务有两种用途 方式:
- 它们使我们能够完成在 特别的机器。例如,无法转换AVI文件 对于使用Linux的Flash(R)电影,我们的Web服务器可能会 继续运行。
- 它们还允许将昂贵的操作转移到其他服务器。这是 例如,在高流量网站上转换视频时非常有用。 < > >
- 删除了依赖项zope.publisher不必要的版本要求。
- 将记录的异常转换为str,因为日志消息应该是字符串。
- 修正了simpleprocessor的一个错误:如果作业中止了事务,它将 从不从队列中删除,而是反复尝试。
- 像intid那样随机生成新的作业id:尝试分配 顺序id,使它们落入同一btree bucket中,并随机化if 偶然发现一个旧的。
- 对cron作业中的可用任务使用下拉小部件 添加表单,而不是文本输入。
- 通过直接使用zope.app.zapi的包装api,消除对zope.app.zapi的依赖。
- 从zope.location而不是zope.app.component中使用ISite
- 使用zc.queue.queue而不是zc.queue.persistentqueue,因为 persistentQueue只能由compositeQueue使用。
- 已将URL更改为PYPI。
- 在 ItaskService.clean
- 跑步会导致归属者。增加了对它的处理
- 在"clearall"期间每100个作业后提交,以避免浏览器超时 同时取消大量工作
- 一些错误被打破,改进了测试。
- 在taskservice.add中添加了startater。更多信息请参见startater.txt。 这有助于分离作业添加和开始时间点。(不像cron)
- 将索引切换到Zope 3.4千克,以便我们就使用的软件包版本达成一致。
- 使处理器变量的睡眠时间;这是测试所需的, 这样测试框架就不会比关闭处理器快 下降。
- 在isprocessing()中添加了一个小优化,以停止查看 找到一个具有正确名称的线程。
- 添加了"全部取消"按钮
- 修复了将线程与任务服务实例关联的错误
- 使初创企业更加稳健 如果已注册的任务服务通过zmi删除,则其注册为 未移除。如果发生这种情况,如果autostart是 使用。
- 允许"*"选择cron作业添加/编辑表单中的所有可能时间
- 允许取消延迟的作业
- 避免折旧警告
- 如果cron作业的状态为error,则不要将其推回到队列中
- 启动期间增强的日志记录功能
- 将索引添加到buildout.cfg
- 增强的自动启动行为:可以启动如下服务:site@*, @服务和*@
- 修复排序中导致列标题无法单击的错误
- 不再需要"jobs"zmi视图的会话支持
- 修复导致处理线程不必要地保持进程活动的错误
- 现在处理任务服务直接在 根。必须开始在产品配置中引用此类服务 使用 @ 而不是 <;sitename>;@
- 将cron作业添加到任务服务的zmi菜单
- 可以为特定于任务的作业注册命名详细视图
- 为cron作业编辑视图
- 改进的ZMI视图
- 如果添加的作业没有为其注册任务,则捕获异常
- 修正了在所有时区工作的测试
- 在以下情况下,不要由于回溯的性能问题而引发索引器错误 使用鸡蛋。
- 在可爱的/uuu init.py中添加了名称空间声明
- 允许延迟作业
安装
在zope.conf中定义启动时应该启动的远程任务 这:
<product-config lovely.remotetask> autostart site1@TestTaskService1, site2@TestTaskService2, @RootTaskService </product-config>
注意,直接在根文件夹中注册的服务可以被引用 只需在它们前面加上 @ 符号。站点名称可以省略。安 这方面的例子是上面引用的roottaskservice。
这会导致远程任务在zope启动时启动。
用法
< Buff行情>>>> STOP_SLEEP_TIME = 0.02
现在让我们从创建单个服务开始:
< Buff行情>>>> from lovely import remotetask >>> service = remotetask.TaskService()
对象应该位于,因此它将获得一个名称:
< Buff行情>>>> from zope.app.folder import Folder >>> site1 = Folder() >>> root['site1'] = site1 >>> from zope.app.component.site import LocalSiteManager >>> from zope.security.proxy import removeSecurityProxy >>> sm = LocalSiteManager(removeSecurityProxy(site1)) >>> site1.setSiteManager(sm)
>>> sm['default']['testTaskService1'] = service >>> service = sm['default']['testTaskService1'] # caution! proxy >>> service.__name__ u'testTaskService1' >>> service.__parent__ is sm['default'] True
让我们用名称注册它 testtaskservice1 :
< Buff行情>>>> from zope import component >>> from lovely.remotetask import interfaces >>> sm = site1.getSiteManager() >>> sm.registerUtility(service, interfaces.ITaskService, ... name='TestTaskService1')
我们可以发现可用的任务:
< Buff行情>>>> service.getAvailableTasks() {}
此列表最初为空,因为我们尚未注册任何任务。让我们 现在定义一个简单回显输入字符串的任务:
< Buff行情>>>> def echo(input): ... return input
>>> import lovely.remotetask.task >>> echoTask = remotetask.task.SimpleTask(echo)
转换器上唯一的api要求是可调用。现在我们确定 任务是否有效:
< Buff行情><product-config lovely.remotetask> autostart site1@TestTaskService1, site2@TestTaskService2, @RootTaskService </product-config>0
现在,我们将任务注册为实用程序:
< Buff行情><product-config lovely.remotetask> autostart site1@TestTaskService1, site2@TestTaskService2, @RootTaskService </product-config>1
echo任务现在在服务中可用:
< Buff行情><product-config lovely.remotetask> autostart site1@TestTaskService1, site2@TestTaskService2, @RootTaskService </product-config>2
由于服务无法立即完成任务,因此传入的作业是 由队列管理。首先,我们请求执行echo任务:
< Buff行情><product-config lovely.remotetask> autostart site1@TestTaskService1, site2@TestTaskService2, @RootTaskService </product-config>3
函数的作用是将名为"echo"的任务调度为 指定的参数。方法返回一个作业id,我们可以用它查询 关于工作。 默认情况下, add() 函数会尽快添加并启动作业。有时我们需要 有一个工作ID但还没有开始工作。请参阅startater.txt how。
< Buff行情><product-config lovely.remotetask> autostart site1@TestTaskService1, site2@TestTaskService2, @RootTaskService </product-config>4
由于作业尚未处理,因此状态设置为"排队"。此外, 目前还没有结果:
< Buff行情><product-config lovely.remotetask> autostart site1@TestTaskService1, site2@TestTaskService2, @RootTaskService </product-config>5
只要不处理作业,就可以取消它:
< Buff行情><product-config lovely.remotetask> autostart site1@TestTaskService1, site2@TestTaskService2, @RootTaskService </product-config>6
默认情况下不会启动服务:
< Buff行情><product-config lovely.remotetask> autostart site1@TestTaskService1, site2@TestTaskService2, @RootTaskService </product-config>7
如果在 zope.conf -只要启动 idatabaseopendevent 。让我们 模拟zope.conf设置:
< Buff行情><product-config lovely.remotetask> autostart site1@TestTaskService1, site2@TestTaskService2, @RootTaskService </product-config>8
注意, roottaskservice 用于服务直接位于 在根目录下注册。我们在单独的脚注中测试这个用例,以便 此文档的流程没有中断。 [3]
要获得一个干净的日志环境,让我们清除日志堆栈:
< Buff行情><product-config lovely.remotetask> autostart site1@TestTaskService1, site2@TestTaskService2, @RootTaskService </product-config>9
在zope启动时,将触发 idatabaseopendevent ,并调用 bootstrap()方法:
< Buff行情>>>> STOP_SLEEP_TIME = 0.020
启动事件:
< Buff行情>>>> STOP_SLEEP_TIME = 0.021
服务正在处理:
< Buff行情>>>> STOP_SLEEP_TIME = 0.022
签出日志将证明已启动的服务:
< Buff行情>>>> STOP_SLEEP_TIME = 0.023
根级别服务中作业的验证在另一个 脚注
要在一个站点中处理大量服务,可以使用 星号(*)启动服务。如果使用site@*表示全部启动 该站点中的服务:
但首先停止所有处理服务:
< Buff行情>>>> STOP_SLEEP_TIME = 0.024
>>> STOP_SLEEP_TIME = 0.025
>>> STOP_SLEEP_TIME = 0.026
并重置记录器:
< Buff行情><product-config lovely.remotetask> autostart site1@TestTaskService1, site2@TestTaskService2, @RootTaskService </product-config>9
使用带星号的服务名称重置产品配置:
< Buff行情>>>> STOP_SLEEP_TIME = 0.028
再次启动该事件将启动配置站点中的所有服务:
< Buff行情>>>> STOP_SLEEP_TIME = 0.029
>>> STOP_SLEEP_TIME = 0.022
>>> from lovely import remotetask >>> service = remotetask.TaskService()1
让我们检查日志:
< Buff行情>>>> from lovely import remotetask >>> service = remotetask.TaskService()2
在很多网站上处理很多服务 星号(*)启动服务。如果使用 @ 表示全部启动 所有站点上的服务:
< Buff行情>>>> STOP_SLEEP_TIME = 0.024
>>> STOP_SLEEP_TIME = 0.026
使用带星号的服务名称重置产品配置:
< Buff行情>>>> from lovely import remotetask >>> service = remotetask.TaskService()5
…并重置记录器:
< Buff行情><product-config lovely.remotetask> autostart site1@TestTaskService1, site2@TestTaskService2, @RootTaskService </product-config>9
再次启动事件。现在应启动所有服务:
< Buff行情>>>> STOP_SLEEP_TIME = 0.029
>>> STOP_SLEEP_TIME = 0.022
>>> from lovely import remotetask >>> service = remotetask.TaskService()9
让我们检查日志:
<阻塞率> 啊!要处理许多站点中的特定服务,可以使用 星号(*)启动服务。如果使用 * 服务,则意味着启动 所有网站上都有名为"服务"的服务:
<阻塞率> 啊! AAAAAH25 啊!使用带星号的服务名称重置产品配置:
<阻塞率> 啊!…并重置记录器:
<阻塞率> 啊!再次启动事件。现在应启动所有服务:
<阻塞率> AAAAAAA 29 啊! 啊!让我们查看日志:
<阻塞率> 啊!如果配置的指令与上的任何服务都不匹配 任何站点日志记录都会显示一条警告消息:
<阻塞率> 啊! 啊! AAAAAAA 52 啊! AAAAAAA 29 啊! 啊! 啊!最后停止处理并终止线程。我们将调用service.process() 由于我们在测试中没有合适的环境,请手动操作。
<阻塞率> 啊! AAAAAH25 啊!现在让我们读一份工作:
<阻塞率> AAAAAAA 61 AAAAAAA 62现在,让我们定义一个导致错误的新任务:
<阻塞率> AAAAAAA 63 AAAAAAA 64现在添加并执行:
<阻塞率> 啊!现在让我们看看发生了什么:
<阻塞率> AAAAAAA 66出于管理目的,该服务还允许您检查所有作业:
<阻塞率> 啊!要摆脱不再需要的工作,可以使用"清除"方法。
<阻塞率> 啊! AAAAAAA 69 啊!cron作业
cron作业在特定时间执行。
<阻塞率> 次级方案71我们安排了一项工作,每小时在当前时刻执行一次。下一个 通话时间是我们从现在开始的时间。
分钟
<阻塞率> AAAAAAA 72小时
<阻塞率> AAAAAAA 73月
<阻塞率> AAAAAAA 741970年1月1日星期[0..6]是星期三。
<阻塞率> 啊!月[1..31]日 <阻塞率> 啊!
组合
<阻塞率> 啊! AAAAAAA 78cron作业也可用于延迟作业的执行。
<阻塞率> AAAAAAA 79创建cron作业
在这里,我们创建一个cron作业,该作业每小时运行10分钟13分钟。
<阻塞率> AAAAAAA 83 AAAAAAA 84我们处理远程任务,但是我们的cron作业没有执行,因为我们也是 早到。
<阻塞率> 啊!现在,我们十分钟后运行远程任务并得到结果。
<阻塞率> AAAAAAA 86一分钟后就不叫了。
<阻塞率> AAAAAAAAA 87但三分钟后它又被调用。
<阻塞率> 啊!可以重新安排作业。
<阻塞率> AAAAAAA 89更新后,必须在服务中重新安排作业。
<阻塞率> 啊哈!现在,在旧的注册分钟(10分钟)不执行作业。
<阻塞率> AAAAAAAAA 91但它在新的一分钟执行,该分钟设置为11。
<阻塞率> 啊!线程行为
每个任务服务在一个单独的线程中运行,允许它们操作碲 独立地。任务的设计应避免 数据库。
我们现在开始定义任务服务,并查看 结果是什么线程正在运行:
< Buff行情>>>> import lovely.remotetask.task >>> echoTask = remotetask.task.SimpleTask(echo)3
>>> import lovely.remotetask.task >>> echoTask = remotetask.task.SimpleTask(echo)4
>>> import lovely.remotetask.task >>> echoTask = remotetask.task.SimpleTask(echo)5
>>> import lovely.remotetask.task >>> echoTask = remotetask.task.SimpleTask(echo)6
让我们添加另一个包含与 第一个站点中的服务:
< Buff行情>>>> import lovely.remotetask.task >>> echoTask = remotetask.task.SimpleTask(echo)7
>>> import lovely.remotetask.task >>> echoTask = remotetask.task.SimpleTask(echo)8
>>> import lovely.remotetask.task >>> echoTask = remotetask.task.SimpleTask(echo)9
让我们用名称注册它 testtaskservice1 :
< Buff行情> α<product-config lovely.remotetask> autostart site1@TestTaskService1, site2@TestTaskService2, @RootTaskService </product-config>00
该服务要求在提交到数据库之前 使用:
< Buff行情><product-config lovely.remotetask> autostart site1@TestTaskService1, site2@TestTaskService2, @RootTaskService </product-config>01
新服务当前未处理:
< Buff行情><product-config lovely.remotetask> autostart site1@TestTaskService1, site2@TestTaskService2, @RootTaskService </product-config>02
如果我们启动新的服务,我们可以看到现在有三个背景 线程:
< Buff行情><product-config lovely.remotetask> autostart site1@TestTaskService1, site2@TestTaskService2, @RootTaskService </product-config>03
让我们停止服务,让后台线程有机会获得 信息:
< Buff行情><product-config lovely.remotetask> autostart site1@TestTaskService1, site2@TestTaskService2, @RootTaskService </product-config>04
>>> STOP_SLEEP_TIME = 0.026
线程已退出:
< Buff行情><product-config lovely.remotetask> autostart site1@TestTaskService1, site2@TestTaskService2, @RootTaskService </product-config>06
脚注
< COL/> < COL/> <正文> <表>[3] | 在 根 级别注册服务的用例测试。 为rootleveltask注册服务 < Buff行情><product-config lovely.remotetask> autostart site1@TestTaskService1, site2@TestTaskService2, @RootTaskService </product-config>07 该对象应该位于,因此get是一个名称: < Buff行情><product-config lovely.remotetask> autostart site1@TestTaskService1, site2@TestTaskService2, @RootTaskService </product-config>08 <product-config lovely.remotetask> autostart site1@TestTaskService1, site2@TestTaskService2, @RootTaskService </product-config>09 |
检查接口和内容
< Buff行情><product-config lovely.remotetask> autostart site1@TestTaskService1, site2@TestTaskService2, @RootTaskService </product-config>14
<product-config lovely.remotetask> autostart site1@TestTaskService1, site2@TestTaskService2, @RootTaskService </product-config>15
<product-config lovely.remotetask> autostart site1@TestTaskService1, site2@TestTaskService2, @RootTaskService </product-config>16
为可爱的远程任务更改
0.5.2(2010-04-30)
0.5.1(2010-04-14)
0.5(2009-09-10)
2009年5月20日(0.4):
2009年4月5日(0.3):
2008/11/07 0.2.15a1:
2008/02/08 0.2.14:
2008年1月28日(新):
2007年12月??(新):
2007年11月12日0.2.13:
2007年10月28日0.2.12:
2007年10月28日0.2.11:
2007年10月24日0.2.10:
2007/10/08 0.2.9:
2007/10/08 0.2.8:
2007年10月02日0.2.7:
2007/08/07 0.2.6:
2007/08/07 0.2.5:
2007/08/06 0.2.4:
2007年7月26日0.2.3:
2007/07/02 0.2.2:
2007/06/12 0.2.1:
2007/06/12 0.2.0:
<块UOT>[4] | 我们验证根目录服务是否得到处理: < Buff行情><product-config lovely.remotetask> autostart site1@TestTaskService1, site2@TestTaskService2, @RootTaskService </product-config>10 正在清理根级别服务: < Buff行情><product-config lovely.remotetask> autostart site1@TestTaskService1, site2@TestTaskService2, @RootTaskService </product-config>11 因此,根服务确实已启用,这正是我们想要验证的。 api的其余部分在上面的主要内容中进行了测试;因此我们不需要 再次测试。我们只是清理根服务。 < Buff行情><product-config lovely.remotetask> autostart site1@TestTaskService1, site2@TestTaskService2, @RootTaskService </product-config>12 <product-config lovely.remotetask> autostart site1@TestTaskService1, site2@TestTaskService2, @RootTaskService </product-config>13 |