Nguyễn Tiến Lộc
Nguyễn Tiến Lộc

Reputation: 33

Flask streamming on heroku still get 30 seconds timeout error

I'm studying Flask and tried to create small website on Heroku. I got timeout error with long task when deploy on Heroku and can by pass with timeout increasement. After investigate more, I found another solution is streamming. Here's article close with my solution: https://librenepal.com/article/flask-and-heroku-timeout/ But it's not work. Error still appears after 30 second Code from the article:

from flask import Flask, Response
import requests

app = Flask(__name__)

def some_long_calculation(number):
  '''
  here will be some long calculation using this number
  let's simulate that using sleep for now :)
  '''
  import time
  time.sleep(5)

  return number

@app.route('/')
def check():
    def generate():
      for i in range(10):
        yield "<br/>"   # notice that we are yielding something as soon as possible
        yield str(some_long_calculation(i))
    return Response(generate(), mimetype='text/html')

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8080, debug=True)

Do you have any idea about this problem?

Upvotes: 3

Views: 3459

Answers (3)

MegaTux
MegaTux

Reputation: 1651

In case it helps you, this is my solution with the streaming support with Ruby and Rails. Even with that support I had to be careful with some response headers settings.

Upvotes: 0

rdegges
rdegges

Reputation: 33854

EDIT: I originally answered this question in 2016 when the below information was true. Today, you can indeed surpass the 30-second timeout using streaming responses.

You cannot get around the 30 second timeout behavior on the request-response cycle on Heroku. This is enforced through the Heroku routing mesh.

If you need to make long-running requests like this, you have a few options:

  1. Put large data into a file on S3 or some other file storage service. When people make a request, send them the file URL, and let them download it there. (this is most optimal)
  2. Use websockets. Web sockets are, by definition, persistent TCP connections that never close between the browser and the server. This is really ideal for apps that require continuous back-and-fourth communication like what you're describing.

Upvotes: 0

UGO
UGO

Reputation: 363

You can avoid heroku's 30 seconds limit by using streaming response, and I just confirmed it's working.

I'm using flask w/ gunicorn in heroku, and the thing that I need to do other than the link's example code is changing the gunicorn timeout settings: web: gunicorn "app.app:create_app()" --timeout 600 in my case. The default timeout was 30 seconds, which happens to be the same as heroku's timeout setup.

Upvotes: 2

Related Questions