starlette icon indicating copy to clipboard operation
starlette copied to clipboard

Don't poll for disconnects in BaseHTTPMiddleware via StreamingResponse

Open adriangb opened this issue 1 year ago • 11 comments
trafficstars

Fixes #2516

adriangb avatar Jun 13 '24 19:06 adriangb

I can confirm that this PR fixes the example I have reproduced in https://github.com/encode/starlette/issues/2516#issuecomment-1976400404

mikkelduif avatar Jun 13 '24 20:06 mikkelduif

I do still recommend you avoid BaseHTTPMiddleware

Maybe we should consider to add a section to: https://www.starlette.io/middleware/#basehttpmiddleware emphasising this. I do not know the exact technicalities for this, however, it might help future users to avoid it.

mikkelduif avatar Jun 14 '24 10:06 mikkelduif

Seems like the issue now is coverage in tests (all of the tests still pass). There are several pieces of test code that are not not being hit but I'm not sure if they were essential or just an implementation detail, some more careful evaluation is needed.

adriangb avatar Jun 14 '24 12:06 adriangb

@adriangb, what is the status of this PR?

avihaiyosef avatar Jul 21 '24 11:07 avihaiyosef

Hi @adriangb , thanks for this fix. Any expectation on when this is going to land in a new release of starlette?

dlahyani avatar Aug 04 '24 14:08 dlahyani

This PR needs someone motivated to check why the coverage dropped.

Anyone that uses BaseHTTPMiddleware in their company, and wants to spend some engineers hours working on this, is welcome.

Otherwise, you can try to sponsor @adriangb as an appreciation gesture for his efforts here, and maybe motivate him to continue the work here.

Kludex avatar Aug 04 '24 15:08 Kludex

@Kludex thanks for the reminder to sponsor, @adriangb has been doing amazing work and we just hit an issue that might be related to this PR so we just started sponsoring (albeit modestly) thru github!!! Would highly recommend anyone else to do the same.

isidentical avatar Aug 13 '24 22:08 isidentical

@Kludex I looked into the coverage.

Basically before we were using StreamingResponse which calls receive() to check for disconnection. Since I changed this to use a similar implementation but one that does not check for disconnection receive() is no longer called.

For example, if I check out master and apply the changes to test_base.py I get the following traceback:

tests/middleware/test_base.py:776: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
starlette/middleware/base.py:189: in __call__
    with collapse_excgroups():
../../.pyenv/versions/3.12.2/lib/python3.12/contextlib.py:158: in __exit__
    self.gen.throw(value)
starlette/_utils.py:89: in collapse_excgroups
    raise exc
starlette/responses.py:265: in __call__
    await wrap(partial(self.listen_for_disconnect, receive))
starlette/responses.py:261: in wrap
    await func()
starlette/responses.py:238: in listen_for_disconnect
    message = await receive()
starlette/middleware/base.py:54: in wrapped_receive
    msg = await self.receive()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

    async def rcv() -> AsyncGenerator[Message, None]:
        yield {"type": "http.request", "body": b"1", "more_body": True}
        yield {"type": "http.request", "body": b"2", "more_body": True}
        yield {"type": "http.request", "body": b"3"}
>       raise AssertionError(  # pragma: no cover
            "Should not be called, no need to poll for disconnect"
        )
E       AssertionError: Should not be called, no need to poll for disconnect

adriangb avatar Aug 21 '24 11:08 adriangb

@Kludex thanks for the reminder to sponsor, @adriangb has been doing amazing work and we just hit an issue that might be related to this PR so we just started sponsoring (albeit modestly) thru github!!! Would highly recommend anyone else to do the same.

Thank you for your sponsorship!

adriangb avatar Aug 21 '24 11:08 adriangb

@Kludex Could you please review this PR when you get a chance? I appreciate your time!

hakanutku avatar Aug 22 '24 08:08 hakanutku

I'm a bit tired of people asking me stuff.

I'm very dedicated to the projects I maintain, which means people just need to wait a bit. I don't like people pressuring me to review stuff.

You want to motivate me to check this PR? Feel free to sponsor me. Otherwise, wait for me to voluntarily come here and review it.

Too many issues regarding BaseHTTPMiddleware, and I need to check previous work and make sure this is fine. It takes time.

Kludex avatar Aug 22 '24 09:08 Kludex