烧瓶长的例程

时间:2012-09-07 11:59:11

标签: python flask gunicorn long-running-processes

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

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

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

    return "Working..."

但是这会造成已经解散的枪支工人。

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

2 个答案:

答案 0 :(得分:11)

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

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

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

当然,您必须考虑存储计算结果的位置以及错误发生的情况。

与芹菜一起使用也很容易。它看起来如下。 要定义要异步执行的函数:

@celery.task
def mytask(data):

    ... do a lot of work ...

然后,不要直接调用任务,例如mytask(data),它会立即执行,使用delay方法:

result = mytask.delay(mydata)

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

result.ready()

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

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

在任何情况下,任何这些解决方案都应该与Flask一起使用。要检查结果,如果您使用Javascript,则无关紧要 。只需创建检查状态的视图返回JSON(您可以使用Flask的jsonify)。

答案 1 :(得分:2)

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

使用芹菜似乎是一种很好的方法。