Fixes Request.json() Hangs Forever#944
Conversation
|
is there a reason nobody had a look at this yet? seems fairly straight forward and fixes an issue that we keep stumbling over. |
|
Any love for this issue? It's been quiet in here for months. |
|
is this fixed by the anyio port? |
|
Any updates? |
|
Would be really nice to see this go in so multiple calls to |
|
Possible to give this a closer look? @tomchristie This would close the following tickets: |
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
|
Are there any progress or discussions going on around this? |
Required removing request body from NoResultFound handler as Starlette hangs on parsing body multiple times (see issue Kludex/starlette/issues/847 PR Kludex/starlette/pull/944).
|
@nikordaris Are you still interested in helping with this PR? |
|
I left a comment on Tom's comment. From my perspective I'm not seeing anything else for me to change with this PR. Let me know if there is anything simple I can tweak on this PR to help it get merged. As I'm no longer on this tech stack I won't likely have time to do any major modifications to this PR |
Exactly, yes. If you access
What I'd like is for the issue to be well described, with a simple-as-possible "this behaviour isn't what I want, when I do this", so we can work through to a better resolution than caching the stream. Having said that I've taken another look at #847 and that's pretty much the sort of thing I'm asking for. The resolution to that (it seems to me) would be to cache the body. (Rather than the stream.) |
|
Ok. Where did you want the cache stored in the scope? In extensions? Directly on the scope? If extensions what namespace? starlette? request_cache? @tomchristie I'll do one more pass at this and then I'm done. I'm not on this tech stack anymore and cant invest any more time on this. Someone else will have to fork my PR and resubmit it with any follow-up changes. My approach will be to cache the raw stream only for body and form. If stream is used directly it will use the cache if it exists. If the stream is consumed and there is no cache then it will raise a runtime error. |
|
Ok, @tomchristie this is ready for review. The |
|
Just bumping by to mention that this is on my personal backlog at the moment, but I don't want to deal with it until I can give it some proper attention, since it's a bit of a fiddly area. Please do feel free to nudge me next week if I don't already get onto looking at it before then. |
Co-authored-by: Adrian Garcia Badaracco <1755071+adriangb@users.noreply.github.com>
…into request-body-cache
|
Okay, so I'd been pushing back against this approach because it changes the nature of streaming the request. If we cache all the data we get when we stream a request, then we're always going to store the entire body in memory. That's find in cases where you're accessing the body (because you needed it all in memory in that cases), or in cases where you're accessing the request as JSON (because, same). Tho it's not ideal in cases where you're accessing There's an alternate approach that'd essentially be to raise an error there's an attempt to stream the request more than once but that does cache the result of However at this point, I'm kinda thinking that we should possibly just suck it up, and accept the trade-off because it results in a much simpler set of "here's what you can and can't do when repeatedly accessing the request content". Anyone? |
I think I agree with what you say, but I'm not understanding the relationship to this PR. My understanding is that currently in Starlette if you do More generally, I think it would make sense to have an API like |
|
@tomchristie it looks like this PR should be closed out in favor of #1519 now, correct? |
|
Thank you @nikordaris for his valiant effort on this!! Looking forward to seeing the resolution to this in #1519 |
This fixes #847 by using the Request scope to store consumed stream data so that new instances of Request can access the Request stream content. Previously
await Request(...).json()followed by anotherawait Request(...).json()would hang forever because thereceivestream was exhausted andawait receive()doesn't timeout after message{"more_body": False}is received. This PR is focused only on enablingRequest.body(),Request.form()andRequest.json()to return the cached data as originally intended and does not address the issue ofawait receive()hanging forever inside ofRequest.stream()