I have a Flask app that, on a form submission, needs to start a new thread. I'm running the app on a free Heroku dyno with Gunicorn, and every time I call either threading.Thread().start()
or gevent.threading.Thread().start()
, the request hangs and ultimately times out. I've put a snippet of the Heroku logs directly below, but, basically, once the worker dies, another one seems to pick up and start the thread no problem, but this ultimately means the form submission takes ages and often requires a refresh.
(Heroku logs): 2021-09-06T07:37:56.372718+00:00 heroku[router]: at=info method=POST path="/form## Heading ##" host=.herokuapp.com request_id=2fcceff4-70d5-4629-bd06-0df682c9a0a9 fwd="152.3.43.49" dyno=web.1 connect=0ms service=29609ms status=200 bytes=4485 protocol=http 2021-09-06T07:37:56.372291+00:00 app[web.1]: [2021-09-06 07:37:56 +0000] [4] [CRITICAL] WORKER TIMEOUT (pid:32)
So far I've tried:
- Using both
gevent
andthreading
threads. - Running my Procfile with
gevent
andeventlet
, with options for --threads and --worker-connections set to 100, as this post suggests. - Running with uWSGI
A simplified reproduction would be something like this:
Procfile: web: gunicorn -k gevent --worker-connections 100 app:app
app.py:
app = Flask(__name__)
@app.route("/form", methods=["POST"])
def form():
t = threading.Thread(target=func, args=(request.form["code"],))
t.setDaemon(true)
t.start()
return render_template("index.html")
def func(code):
while True:
# do stuff (loop will not terminate)