7

我必须在我的 Flask 应用程序中做一些长时间的工作。我想异步进行。刚开始工作,然后从 javascript 检查状态。

我正在尝试做类似的事情:

@app.route('/sync')
def sync():
    p = Process(target=routine, args=('abc',))
    p.start()

    return "Working..."

但这创造了不复存在的独角兽工人。

如何解决?我应该使用像芹菜这样的东西吗?

4

2 回答 2

11

有很多选择。您可以开发自己的解决方案,使用 Celery 或 Twisted(我相信还有更多已经制作好的选项,但这些是最常见的选项)。

开发您的内部解决方案并不困难。可以使用multiprocessingPython 标准库的模块:

  • 当任务到达时,您在数据库中插入一行,其中包含任务 ID 和状态。
  • 然后启动一个进程来执行在完成时更新行状态的工作。
  • 你可以有一个视图来检查任务是否完成,实际上只是检查相应的状态。

当然,您必须考虑要将计算结果存储在哪里以及错误会发生什么。

与芹菜一起去也很容易。它看起来如下所示。定义一个异步执行的函数:

@celery.task
def mytask(data):

    ... do a lot of work ...

然后,不要直接调用任务,比如直接mytask(data)执行它,而是使用以下delay方法:

result = mytask.delay(mydata)

最后,您可以检查结果是否可用ready

result.ready()

但是,请记住,要使用 Celery,您必须运行外部工作进程。

我从来没有看过 Twisted,所以我不能告诉你它是否比这更复杂(但也可以做你想做的事情)。

无论如何,这些解决方案中的任何一个都应该适用于 Flask。要检查结果,如果您使用 Javascript则完全没有关系。只需使检查状态的视图返回 JSON(您可以使用 Flask 的jsonify)。

于 2012-09-07T12:56:50.460 回答
2

我会使用消息代理,例如rabbitmq 或activemq。烧瓶进程会将作业添加到消息队列中,而长时间运行的工作进程(或池或工作进程)将从队列中取出作业以完成它们。工作进程可以更新数据库以允许烧瓶服务器知道作业的当前状态并将此信息传递给客户端。

使用 celery 似乎是一个不错的方法。

于 2012-09-07T14:49:29.663 回答