pallets/flask

Resource leaking in http-stream-request

GoddessLuBoYan opened this issue · 3 comments

If I stop a stream request before it's finished, the stream function will never finish, without any exception or warning.
So, if I want to release something (such as threading.Lock) in the end of the function, I will never be able to release it.

Here's an example.

# flask server
import time
from flask import *


def stream():
    print("acquire something")
    for i in range(5):
        yield str(i)
        time.sleep(1)
    print("release something")


app = Flask(__name__)


@app.route("/")
def _():
    return Response(stream())


if __name__ == '__main__':
    app.run("0.0.0.0", 45678)

when I request it and stop it early (for example, I'm timeout)

>>> curl http://localhost:45678 --max-time 2
01curl: (28) Operation timed out after 2002 milliseconds with 2 bytes received

then, the function stream() will never stopped, here's the log.

acquire something
127.0.0.1 - - [13/Aug/2023 18:17:01] "GET / HTTP/1.1" 200 -

I wish, flask will do like one of these:

  • throw a ResourceWarning when the request has stopped
  • run stream() to the end, whatever the request stop or not
  • if stream() is an AsyncIterator(Coroutine), send an Exception into it when the request has stopped

Environment:

  • Python version: 3.9
  • Flask version: 2.2.3

It would be up to the WSGI server to close the response or destroy the worker. It's not something the WSGI application (Flask) can control. There's no way to do the things you suggest from our end.

I see, it's a bug from werkzeug, not from Flask. Thanks.

Werkzeug is also the application side. If you're referring to the dev server, it won't be fixed there. Use a production WSGI server.