"Working outside of request context" Celery 后台任务出错
"Working outside of request context" error with Celery background task
我有一个简单的 Python Flask/Celery 应用程序 运行 遇到延迟后闪烁消息的问题。我正在使用 Celery 的 delay() 函数来调用一个休眠 5 秒的函数,然后闪烁一条消息。尽管在我的后台函数中使用了 with app.app_context()
,但 Celery 报告:
RuntimeError: Working outside of request context
我也尝试了 @copy_current_request_context
装饰器,如 this question 所述,但后来我得到了
RuntimeError: This decorator can only be used at local scopes when a request context is on the stack. For instance within view functions
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')
templates/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 %}
我是 运行 具有三个终端的应用程序 windows:运行 Redis 与 redis-server
,运行 Celery 与 celery worker -A app.celery --loglevel=info
, 运行 Python 和 python app.py
.
问题是 celery 任务是由 celery 运行 完成的,它们不是浏览器或任何其他客户端完成的请求的一部分,因此它们将始终不受约束,因为它们不知道要做什么他们应该回复的客户。
运行 除非我们使用 websockets 或服务器发送的事件,否则后台任务并不真正意味着与客户端交互,而是触发其他工作(例如发送电子邮件)。
我有一个简单的 Python Flask/Celery 应用程序 运行 遇到延迟后闪烁消息的问题。我正在使用 Celery 的 delay() 函数来调用一个休眠 5 秒的函数,然后闪烁一条消息。尽管在我的后台函数中使用了 with app.app_context()
,但 Celery 报告:
RuntimeError: Working outside of request context
我也尝试了 @copy_current_request_context
装饰器,如 this question 所述,但后来我得到了
RuntimeError: This decorator can only be used at local scopes when a request context is on the stack. For instance within view functions
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')
templates/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 %}
我是 运行 具有三个终端的应用程序 windows:运行 Redis 与 redis-server
,运行 Celery 与 celery worker -A app.celery --loglevel=info
, 运行 Python 和 python app.py
.
问题是 celery 任务是由 celery 运行 完成的,它们不是浏览器或任何其他客户端完成的请求的一部分,因此它们将始终不受约束,因为它们不知道要做什么他们应该回复的客户。
运行 除非我们使用 websockets 或服务器发送的事件,否则后台任务并不真正意味着与客户端交互,而是触发其他工作(例如发送电子邮件)。