跳转到主要内容

为从Zope运行异步进程提供基本视图。

项目描述

简介

netsight.async为Zope Web框架提供基本浏览器视图,允许浏览器请求在后台运行,同时将请求的进度返回给浏览器。

用法

基本用法

首先,从BaseAsyncView类继承。您可能通常会在视图类的__call__方法中编写代码以执行某些过程,而是将其放置在__run__方法中。

>>> import time
>>> from netsight.async.browser.BaseAsyncView import BaseAsyncView
>>> class MyView(BaseAsyncView):
...
...    def __run__(self, *args, **kwargs):
...         time.sleep(30)
...         return "Hello world!"
...
>>>

当您从浏览器调用此视图时,它将显示正常配置的任何输出。但是,当您向视图执行POST请求时,后台将调用__run__方法,就像调用视图类的__call__方法一样。同时,将向浏览器返回显示旋转器的页面,并在__run__定义的过程完成之前每5秒轮询一次。

__run__方法完成后,浏览器将重定向到结果页面。

示例时间线

  1. 用户访问‘/myview’并看到一个表单。

  2. 用户提交表单,后台启动该过程。

  3. 用户被重定向到显示旋转器的‘/myview/processing?process_id=abcde-f01234’。

  4. 如果可能,用户的当前页面将通过AJAX轮询最多30秒的过程状态,否则通过页面刷新。

  5. 一旦过程完成,用户将被重定向到显示“Hello world!”的‘/myview/result?process_id=abcde-f01234’。

与页面模板一起使用

如果您已经为您的视图类配置了带有在ZCML中指定的页面模板文件的浏览器视图,则首次调用视图时将默认显示该模板。如果向视图提交POST请求,则将启动过程。您可以通过重写视图的initial_pagerun_process方法来更改初始模板和启动过程的条件。

>>> from Products.Five.browser.pagetemplatefile import \
...      ViewPageTemplateFile
>>>
>>> class MyView(BaseAsyncView):
...
...     def run_process(self):
...         return 'run' in self.request.form
...
...     initial_page = \
...         ViewPageTemplateFile('templates/my_template.pt')
...
>>>

或者,您也可以使用一个方法

>>> class MyView(BaseAsyncView):
...
...     def initial_page(self, *args, **kwargs):
...         return 'Hello world!'
...
>>>

您还可以通过重写processing_page方法来覆盖启动过程后返回给浏览器的页面。

如果您想在__run__方法中调用ZCML中定义的模板,并且如果您的run_process方法通常会再次启动过程,则可以在调用方法中传递一个名为no_process的值为True的参数。

>>> class MyView(BaseAsyncView):
...
...     def __run__(self, *args, **kwargs):
...         return self.__call__(message="Hello world",
...                              no_process=True)
...
>>>

检查状态和检索结果

一旦启动了您的__run__方法,结果响应将重定向到处理视图,其中包含新启动过程的唯一ID,作为GET变量process_id

此过程ID可以用来检索关于过程状态及其结果的信息。

通过将过程ID传递给视图的completed方法,将返回一个表示完成状态的TrueFalse,或者表示100%(稍后详细介绍进度记录)。如果可选参数output_json设置为某些评估为True的值,则方法返回一个包含单个键completed的JSON对象,其中包含相同的TrueFalse或数值。

如果您的过程在完成之前死亡,它将引发错误,或者如果选择JSON输出,则返回字符串值ERROR作为completed

一旦__run__方法完成,请使用过程ID调用视图的result方法来检索结果。

如果您的过程在完成之前死亡,这也会引发错误,或者如果选择JSON输出,则返回字符串值ERROR作为completed

如果调用result时过程尚未完成,将返回None

从您的任务设置过程进度

如果您想让您的任务返回某些完成度,可以调用带有过程ID和一些数值的set_progress方法。

>>> class MyView(BaseAsyncView):
...
...    def __run__(self, process_id=None, *args, **kwargs):
...         time.sleep(15)
...         self.set_progress(process_id, 50)
...         time.sleep(15)
...         return "Hello world!"
...
>>>

当您的任务完成而不引发异常时,进度将自动设置为100,因此不需要在方法返回之前设置此值。

安装

只需将 netsight.async 添加到您的 buildout 配置中的 eggs 部分。如果您还计划使用内置的 ‘processing’ 页面,您可能还需要将其添加到 zcml 部分。

[buildout]
eggs = ...
       netsight.async
zcml = ...
       netsight.async

局限性

由于新进程无法使用 Zope 池中的现有线程运行,因此在异步进程期间,Zope 进程将创建一个额外的线程,超过正常线程限制。这也意味着将打开额外的 ZODB 连接,超过正常连接限制,这可能导致在控制台或日志文件中显示警告。

一旦 __run__ 方法开始运行,用户就无法以任何方式停止它。这是一个子类可以选择实现的功能,但在不了解后台任务做什么以及需要哪些清理的情况下,在此包中实现此功能是危险的。

待改进

目前进程存储在特定 Python 实例的内存中。这引入了以下问题

  • 如果用户从未从 __run__ 方法检索结果,则它们将永久存储在 ZODB 中。

依赖关系

  • Python>=2.4.0

  • zope.component>=3.4.0

  • zope.i18n>=3.4.0

  • zope.i18nmessageid>=3.4.0

  • zope.publisher

  • Zope>=2.8.0

默认处理页面模板依赖于提供的主模板,类似于 Products.CMFPlone 提供的模板,但如上所述,这可以被您自己的视图覆盖。

贡献

您可以在以下位置找到此项目的源代码:

http://github.com/netsight/netsight.async

此产品需要翻译!只需翻译 2 个字符串,因此这是一个为开源项目做出贡献的快速且简单的方法。

欢迎提交任何错误修复、新功能及文档改进,只需在 github 上提交拉取请求即可。

变更日志

1.1.1 - (2011-10-27)

  • 修复了进度设置为 100 时的进程完成检测。

1.1.0 - (2011-10-27)

  • 使 Python 2.4 兼容。

  • 进程进度/结果存储现在在 ZODB 中,而不是在 Python 实例的内存中。

1.0.1 - (2011-10-19)

  • 修复了包清单。

  • 修复了处理页面上的标记。

1.0.0 - (2011-10-19)

初始版本。

许可证

版权所有 2011 Netsight Internet Solutions Limited

根据 Apache License,版本 2.0(“许可证”);除非遵守许可证,否则不得使用此文件。您可以在以下位置获取许可证的副本:

https://apache.ac.cn/licenses/LICENSE-2.0

除非适用法律要求或书面同意,否则根据许可证分发的软件按“原样”提供,不提供任何明示或暗示的保证或条件。有关许可证的具体语言、权限和限制,请参阅许可证。

项目详细信息


下载文件

下载适用于您的平台的文件。如果您不确定要选择哪个,请了解更多关于 安装包 的信息。

源代码分发

netsight.async-1.1.1.zip (28.1 kB 查看哈希值)

上传时间 源代码

支持者