我有一个简单的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。
答案 0 :(得分:1)
问题是芹菜任务是由芹菜运行的,它们不是浏览器或任何其他客户提出的请求的一部分,所以它们总是不受约束,因为他们不知道他们应该使用什么客户端回复。
运行后台任务并不意味着与客户端进行交互,而是触发其他工作(例如发送电子邮件),除非我们使用的是websockets或服务器发送的事件。