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')
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.
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.
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With