tl; dr Un metodo decorato con route
non può gestire richieste simultanee mentre Flask viene servito dietro una gunicorn avviata con più worker e thread, mentre due metodi diversi gestiscono le richieste simultanee. Perché è così, e in che modo la stessa rotta può essere servita contemporaneamente?Come ottenere Flask/Gunicorn per gestire richieste simultanee per lo stesso percorso?
ho questa semplice applicazione pallone:
from flask import Flask, jsonify
import time
app = Flask(__name__)
@app.route('/foo')
def foo():
time.sleep(5)
return jsonify({'success': True}), 200
@app.route('/bar')
def bar():
time.sleep(5)
return jsonify({'success': False}), 200
Se corro questa via:
gunicorn test:app -w 1 --threads 1
Se apro rapidamente /bar
e /foo
in due diverse schede in un browser, la scheda che premo invio per prima verrà caricata in 5 secondi e la seconda scheda verrà caricata in 10 secondi. Questo ha senso perché gunicorn esegue un lavoratore con un thread.
Se corro questa tramite uno:
gunicorn test:app -w 1 --threads 2
gunicorn test:app -w 2 --threads 1
In questo caso, l'apertura e /foo
/bar
in due diverse schede prendono entrambi 5 secondi. Questo ha senso, perché gunicorn esegue sia 1 worker con due thread, o due worker con un thread ciascuno, e può servire le due rotte allo stesso tempo.
Tuttavia, se apro due /foo
allo stesso tempo, indipendentemente dalla configurazione di gunicorn, la seconda scheda richiederà sempre 10 secondi.
Come è possibile ottenere lo stesso metodo decorato da route
per soddisfare richieste simultanee?
Interessante che originariamente il comportamento di tale browser riguardo alle connessioni è inteso a * accelerare * il caricamento evitando il sovraccarico extra di stabilire nuove connessioni. Ma in questa situazione (con una gestione lenta dal lato server) vediamo che può rallentare le cose. – MarSoft
Ho appena provato con una scheda in Chrome e una scheda in Firefox e ho ricevuto i risultati previsti. Grazie e bella chiamata. –