1

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 and threading threads.
  • Running my Procfile with gevent and eventlet, 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)
GLaw1300
  • 195
  • 9

1 Answers1

0

For anyone who cares, I've found a solution that works for me using eventlet and eventlet.spawn:

Procfile: web: gunicorn --worker-class eventlet -w 1 app:app

app.py:

import eventlet
eventlet.monkey_patch()

app = Flask(__name__)

@app.route("/form", methods=["POST"])
def form():
    eventlet.spawn(func,request.form["code"]) # the solution I found
    return render_template("index.html")

def func(code):
    while True:
        # do stuff (loop will not terminate)

GLaw1300
  • 195
  • 9