Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flask, processing requests 1 by 1

Tags:

python

flask

I have a flask application which listens for some job to do. The process is quite long (let us say 1 minute) and I would like not allow to process two requests at the same time.

I will be great if once I receive a request, I could close the port flask is listening to and open again when finish. Alternatively I could setup a semaphore but I am not sure about how flask is running concurrently.

Any advice?

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')
like image 650
mosh442 Avatar asked Feb 19 '17 08:02

mosh442


People also ask

How many requests can Flask handle at once?

Flask will process one request per thread at the same time. If you have 2 processes with 4 threads each, that's 8 concurrent requests.

Can Flask handle multiple requests at once?

Flask applications are deployed on a web server, either the built-in server for development and testing or a suitable server (gunicorn, nginx etc.) for production. By default, the server can handle multiple client requests without the programmer having to do anything special in the application.

How does a Flask handle a request?

Flask uses the term context local for this. Flask automatically pushes a request context when handling a request. View functions, error handlers, and other functions that run during a request will have access to the request proxy, which points to the request object for the current request.

Is python Flask single threaded?

As of Flask 1.0, flask server is multi-threaded by default. Each new request is handled in a new thread. This is a simple Flask application using default settings.


1 Answers

You could use a semaphore for this:

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"

The semaphore usage is to control the access to a common resource.

You can see more info about semaphore in here

This SO question can help you as well here

EDIT:

As Georg Schölly wrote in comment, The above mentioned solution is problematic in a situation of multiple services.

Although, you can use the wsgi in order to accomplish your goal.

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

uWSGI supports a configurable number of locks you can use to synchronize worker processes

For more info, read here

like image 150
omri_saadon Avatar answered Oct 20 '22 15:10

omri_saadon