我正在开发的Web应用程序需要执行在http请求/响应周期中执行太长而无法执行的任务。通常,用户将执行请求,服务器将接受此请求,并且除其他外,运行一些脚本以生成数据(例如,使用povray渲染图像)。
当然,这些任务可能需要很长时间,因此在将响应发送到客户端之前,服务器不应挂起以使脚本完成执行。因此,我需要执行脚本async的执行,并给客户端“资源在这里,但没有准备好”,并可能告诉它一个ajax端点进行轮询,因此它可以在准备好时检索并显示资源。
现在,我的问题与设计无关(尽管我非常喜欢这方面的任何提示)。我的问题是:解决这个问题的系统是否已经存在,所以我不重新发明方形轮?如果必须的话,我会使用进程队列管理器来提交任务并放置一个HTTP端点来发送状态,例如“pending”,“aborted”,“completed”到ajax客户端,但是如果已经类似了专门为这项任务而存在,我会非常喜欢它。
我在python + django工作。
编辑:请注意,此处的主要问题不是服务器和客户端必须如何协商和交换有关任务状态的信息。
问题是服务器如何处理很长任务的提交和入队。换句话说,我需要一个比我的服务器在LSF上提交脚本更好的系统。并不是说它不起作用,但我觉得它有点太多了......
编辑2 :我添加了赏金以查看是否可以获得其他答案。我检查了pyprocessing,但我无法执行提交作业并在稍后阶段重新连接到队列。
答案 0 :(得分:4)
你应该避免在这里重新发明轮子。
结帐gearman。它有很多语言的库(包括python),并且相当受欢迎。不确定是否有任何开箱即用的方法可以轻松地将django连接到gearman和ajax调用,但是自己做这部分并不是很复杂。
基本思想是你运行gearman作业服务器(或多个作业服务器),让你的web请求排队一个工作(比如'resize_photo')和一些参数(比如'{photo_id:1234}')。您将此作为后台任务排队。你得到一个回头。然后,您的ajax请求将轮询该句柄值,直到它被标记为完成。
然后你有一个工作者(或者可能很多)是一个单独的python进程连接到这个作业服务器并为“resize_photo”作业注册自己,做了工作,然后将其标记为完成。
我还发现这个blog post能够很好地总结它的用法。
答案 1 :(得分:1)
您可以尝试两种方法:
"loading"
,并且每次收到新数据时都需要收集新信息。关于第二个选项,您可以通过阅读Comet了解更多信息;使用ASP.NET,您可以通过实现System.Web.IHttpAsyncHandler接口来做类似的事情。
答案 2 :(得分:1)
我不知道有哪个系统可以做到这一点,但实现自己的系统会相当容易:
有一些边缘情况可以照顾,所以现有的框架显然会更好,就像你说的那样。
答案 3 :(得分:1)
首先你需要一些单独的“工作”服务,它将在通电时单独启动,并通过一些本地IPC(如UNIX-socket(快速)或数据库(简单))与http-request处理程序进行通信。
在处理请求期间,cgi从工作人员状态或其他数据询问并重播给客户。
答案 4 :(得分:0)
您可以通过回复202 HTTP代码来表示资源正在“处理”:客户端将不得不稍后重试以获取已完成的资源。根据具体情况,您可能必须发出“请求ID”才能将请求与响应匹配。
或者,您可以查看现有的COMET库,这些库可能会“开箱即用”地满足您的需求。我不确定是否有任何匹配你当前的Django设计。
答案 5 :(得分:0)
对于您正在使用的python / django解决方案,可能不是一个很好的答案,但我们使用Microsoft Message Queue来做这样的事情。它基本上就像这样运行
无论如何,这是它的要点。它对我们来说非常可靠,并且非常直接地进行扩展和管理。
-al
答案 6 :(得分:0)