有几个不同的答案在不同的情况下都是有效的。快速的回答是,像 RQ 这样的作业队列通常是正确的解决方案,尤其是从长远来看,随着项目的增长。
只要 WSGI 服务器有可用的工作人员,就可以处理另一个请求。每个工作人员一次处理一个请求。开发服务器使用线程,因此可用的工作线程数量不受限制(受 Python 中线程的性能限制)。像 Gunicorn 这样的生产服务器可以使用多个 worker,以及不同类型的 worker,例如线程、进程或 eventlet。如果您想运行一个任务以响应 HTTP 请求并等到任务完成发送响应,您将需要足够的工作人员来阻止这些任务以及处理常规请求。
@app.route("/admin/send-purchases")
def send_purchases():
... # do stuff, wait for it to finish
return "success"
但是,您所描述的任务似乎是一个清理任务,无论用户的 HTTP 请求如何,都应该运行该任务。在这种情况下,您应该编写一个 Flask CLI 命令并使用 cron 或其他调度系统调用它。
@app.cli.command()
def send_purchases():
...
click.echo("done")
# crontab hourly job
0 * * * * env FLASK_APP=myapp /path/to/venv/bin/flask send-purchases
如果您确实希望用户启动任务,但又不想阻止等待它完成的工作人员,那么您需要一个任务队列,例如 RQ 或 Celery。您也可以创建一个提交作业的 CLI 命令,以便能够按请求和按计划触发它。
@rq.job
def send_purchases():
...
@app.route("/admin/send-purchases", endpoint="send_purchases")
def send_purchases_view():
send_purchases.queue()
return "started"
@app.cli.command("send-purchases")
def send_purchases_command():
send_purchases.queue()
click.echo("started")