Flask,处理1个1的请求

时间:2017-02-19 08:26:07

标签: python flask

我有一个烧瓶应用程序,听取一些工作要做。这个过程很长(让我们说1分钟),我不希望同时处理两个请求。

如果我收到请求,我会很高兴,我可以关闭端口烧瓶正在收听并在完成后再次打开。或者我可以设置一个信号量,但我不确定瓶子是如何同时运行的。

有什么建议吗?

from flask import Flask, request
app = Flask(__name__)

@app.route("/",methods=['GET'])
def say_hi():
    return "get not allowed"

@app.route("/",methods=['POST'])
def main_process():
    # heavy process here to run alone
    return "Done"

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

2 个答案:

答案 0 :(得分:2)

您可以使用信号量:

import threading
import time
sem = threading.Semaphore()

@app.route("/",methods=['POST'])
def main_process():
    sem.acquire()
    # heavy process here to run alone
    sem.release()
    return "Done"

信号量用法是控制对公共资源的访问。

您可以在here

中查看有关信号量的更多信息

此SO问题也可以为您提供帮助here

修改

正如GeorgSchölly在评论中所写,上述解决方案在多种服务的情况下存在问题。

虽然,您可以使用wsgi来实现目标。

@app.route("/",methods=['POST'])
def main_process():
    uwsgi.lock()
    # Critical section
    # heavy process here to run alone
    uwsgi.unlock()
    return "Done"

uWSGI支持可用于同步工作进程的可配置数量的锁

有关详情,请参阅here

答案 1 :(得分:0)

您可以尝试添加threading.Lock来表示某些工作已在进行中:

import threading
from contextlib import ExitStack

busy = threading.Lock()
@app.route("/",methods=['POST'])
def main_process():
    if not busy.acquire(timeout = 1):
        return 'The application is busy, refresh the page in a few minutes'

    # ensure busy.release() is called even if an exception is thrown
    with ExitStack() as stack:
        stack.callback(busy.release)
        # heavy process here to run alone

    return "Done"

但Flask默认情况下一次只允许处理一个请求(更多信息here),所以如果您对处理单个请求期间的所有其他用户感到满意在完成该过程之前不会加载页面(甚至可能会出现请求超时错误),您不必更改任何内容 如果你想让其他用户得到一条消息,就像在上面的代码中那样,将工作量增加到2,这样当一个工人处理请求时,另一个工人会阻止其他工作。