Celery后台任务

时间:2017-05-26 16:23:31

标签: python asynchronous flask celery

我有一个简单的Python Flask / Celery应用程序,在延迟后遇到闪烁消息的问题。我正在使用Celery的delay()函数调用一个睡眠5秒的函数,然后闪烁一条消息。尽管在我的后台函数中使用with app.app_context(),但Celery报告:

  

RuntimeError:在请求上下文之外工作

我已经尝试了@copy_current_request_context装饰,如this question所述,但后来我

  

RuntimeError:当请求上下文在堆栈上时,此装饰器只能在本地作用域使用。例如在视图函数

app.py:

from flask import Flask, flash, render_template, request
from celery import Celery
import time

app = Flask(__name__)
app.config['CELERY_BROKER_URL'] = 'redis://localhost:6379/0'
app.config['CELERY_RESULT_BACKEND'] = 'redis://localhost:6379/0'

celery = Celery(app.name, broker=app.config['CELERY_BROKER_URL'])
celery.conf.update(app.config)

@celery.task
def my_background_task():
    with app.app_context():
        time.sleep(5)
        flash("Background task complete.")

@app.route("/", methods=["GET", "POST"])
def index():
    if request.method == "POST":
        task = my_background_task.delay()
        return render_template("index.html")
    else:
        return render_template("index.html")

if __name__ == "__main__":
    app.run(debug=True,host='0.0.0.0')

模板/ index.html中:

<!doctype html>
{% with messages = get_flashed_messages() %}
    {% if messages %}
        <ul class=flashes>
        {% for message in messages %}
            <li>{{ message }}</li>
        {% endfor %}
        </ul>
    {% endif %}
{% endwith %}

{% block body %}
<form method="POST">
    <input type="submit" name="submit" value="Submit request">
</form>
{% endblock %}

我正在使用三个终端窗口运行应用程序:使用redis-server运行Redis,使用celery worker -A app.celery --loglevel=info运行Celery,并使用python app.py运行Python。

1 个答案:

答案 0 :(得分:1)

问题是芹菜任务是由芹菜运行的,它们不是浏览器或任何其他客户提出的请求的一部分,所以它们总是不受约束,因为他们不知道他们应该使用什么客户端回复。

运行后台任务并不意味着与客户端进行交互,而是触发其他工作(例如发送电子邮件),除非我们使用的是websockets或服务器发送的事件。