2011-12-29 70 views
7

我需要在控制器方法内调用的web2py应用程序中异步处理大型(耗时且耗费内存的)进程。使用web2py异步后台进程

我的具体用例是通过stdlib.subprocess调用一个进程,并等待它退出而不阻塞网络服务器,但我接受其他方法。

  • 动手的例子是一个加号。
  • 欢迎第三方图书馆推荐 。
  • CRON调度不是必需/想要的。

回答

7

假设你需要启动后台任务的多个可能同时的,情况下,解决方案是一个任务队列。如果您正在寻找第三方选项,我已经听说过关于Celery和RabbitMQ的好消息,并且web2py包含了可能足以满足您的需求的it's own task queue系统。

使用任何一种工具,您都可以定义一个函数来封装您希望后台进程执行的操作。然后使任务队列工作人员联机。 web2py手册和论坛指出,这可以通过web2py cron系统中的@reboot语句完成,每当Web服务器启动时都会触发该语句。如果情况不理想,可能还有其他方法来启动员工。

在你的控制器,你将插入一个任务到任务队列,传递任何必要的参数作为函数的输入(后台功能不会在相同的环境中运行控制,所以不会有机会获得会话,数据库等,除非您明确地将适当的值传递给任务函数)。

现在,获取后台操作的输出给用户。当您将任务插入任务队列时,您应该获取该任务的唯一ID。然后,您将实现控制器逻辑(要么是AJAX调用,要么是保持刷新直到任务完成的页面),调用任务队列的API来检查指定任务的状态。如果任务状态为“已完成”,则将数据返回给用户。如果没有,请继续等待。

+0

我觉得内置的任务调度只是我一直在寻找。 – 2011-12-30 00:29:17

1

这比人们所预料的更加困难。请注意0​​中的死锁警告。如果你不介意阻塞,使用Popen.communicate很容易。要解决阻塞问题,可以使用stdlib.subprocess从线程管理进程。

我最喜欢的方式来处理子过程是使用Twisted's spawnProcess。但是,让Twisted与其他框架很好地搭配并不容易。