Always close the response_stream after HTTP.request#467
Always close the response_stream after HTTP.request#467bors[bot] merged 8 commits intoJuliaCloud:masterfrom
response_stream after HTTP.request#467Conversation
- We need to explicitly close the `response_stream` (`HTTP.request` no longer closes it for us) in HTTP.jl v0.9.15+ (see HTTP.jl JuliaCloud#752) - Since `close` is safe to call multiple times, this should be compatible with old HTTP.jl versions. - Should fix issue JuliaCloud#466
|
I'm a bit worried about the |
i suppose we could just call e.g. - return @mock HTTP.request(
+ resp = @mock HTTP.request(
http_stack,
request.request_method,
HTTP.URI(request.url),
HTTP.mkheaders(request.headers),
request.content;
require_ssl_verification=false,
response_stream=request.response_stream,
http_options...,
)
+ request.response_stream === nothing || close(request.response_stream)
+ return resp
catch e
+ request.response_stream === nothing || close(request.response_stream)
# Base.IOError is needed because HTTP.jl can often have errors that aren't |
|
The semantics of these macros are pretty confusing; both the |
|
:oof: macros 😒 okay, well 🤞 they play nice with suggestions for tests are very welcome 😊 for now i'm struglling to recreate the original issue with just AWS.jl (not AWSS3.jl) for a test 😅 |
Co-authored-by: Fredrik Ekre <ekrefredrik@gmail.com>
|
Let’s see what CI says already— we can check at least if tests pass here with the new HTTP.jl release. bors try |
|
Tests pass and we are using HTTP v0.9.15: https://github.com/JuliaCloud/AWS.jl/runs/3733253932#step:10:48 so that’s promising |
|
What's a sensible way to test something that causes code to hang? For now i've just put some code (which hangs on |
|
We at least have timeouts now (https://github.com/JuliaCloud/AWS.jl/blob/master/.github/workflows/CI.yml#L16) due to hangs in the past, so I think the way you did it is OK. Should we be creating buckets, or is there one we should use already @mattBrzezinski ? |
ah yeah, i meant to ask -- the |
| (isa(e, HTTP.StatusError) && _http_status(e) >= 500) | ||
| end | ||
| finally | ||
| request.response_stream isa IO && close(request.response_stream) |
There was a problem hiding this comment.
If an end-user were to pass in their own response_stream, what would happen here if it closes? Is that data still available in it, or does it go away?
There was a problem hiding this comment.
I was gonna suggest something like
diff --git a/src/utilities/request.jl b/src/utilities/request.jl
index 12debd4..2ef8363 100644
--- a/src/utilities/request.jl
+++ b/src/utilities/request.jl
@@ -189,11 +189,13 @@ function _http_request(http_backend::HTTPBackend, request::Request)
@repeat 4 try
http_stack = HTTP.stack(; redirect=false, retry=false, aws_authorization=false)
+ should_close = false
if request.return_stream && request.response_stream === nothing
request.response_stream = Base.BufferStream()
+ should_close = true
end
- return @mock HTTP.request(
+ r = @mock HTTP.request(
http_stack,
request.request_method,
HTTP.URI(request.url),
@@ -203,6 +205,10 @@ function _http_request(http_backend::HTTPBackend, request::Request)
response_stream=request.response_stream,
http_options...,
)
+ if should_close
+ close(request.response_stream)
+ end
+ return r
catch e
# Base.IOError is needed because HTTP.jl can often have errors that aren't
# caught and wrapped in an HTTP.IOErrorearlier. E.g. only close if it was opened internally.
There was a problem hiding this comment.
the behaviour is exactly as before (i.e. as we had with older HTTP.jl versions). In older HTTP versions, close was already called inside the HTTP.request above https://github.com/JuliaWeb/HTTP.jl/pull/752/files#diff-2877f0a59db9c7dda95204097d3c2010021eb8f6c59c98d56d3f7d16e38b0acbL149
There was a problem hiding this comment.
the behaviour is exactly as before (i.e. as we had with older HTTP.jl versions)
I think the idea is that this maybe wasn't correct from HTTP.jl which is why it got changed there. #396 (comment) and #433 have lots of discussion on this (which I forgot completely about until just now)
There was a problem hiding this comment.
only close if it was opened internally
wouldn't this be different behaviour to what we had when using older HTTP.jl versions?
i.e. didn't HTTP.request just call close on the response_stream (if it wasn't nothing)?
(i don't know, since i'm not too familiar with this stuff)
There was a problem hiding this comment.
I have not been paying too much attention to the HTTP.jl changes. Are there use cases anyone can think of to keeping the streams open and having users manually close them?
Personally I think closing the HTTP requests automatically makes sense. It gives a loose contract of, this is the data which AWS has provided you from your request.
Maybe I'm missing something obvious though.
There was a problem hiding this comment.
Yea, maybe it should be reverted.
There was a problem hiding this comment.
FWIW, i have no opinion on how best to fix this. But i am keen to fix it as fast as possible, as not being able get files from S3 is quite debilitating for some workflows at Invenia 😊
There was a problem hiding this comment.
Yes, I would say we should merge this PR which basically brings back the behavior of HTTP 0.9.14 and then continue this discussion in an issue.
I would really like to see this merged today.
mattBrzezinski
left a comment
There was a problem hiding this comment.
LGTM, left a couple comments.
mattBrzezinski
left a comment
There was a problem hiding this comment.
One comment about the try/finally in test/issues.jl and it LGTM!
|
FWIW You should be able to just run JuliaFormatter w/ BlueStyle on the entire package and it'll make the CI step happy. I believe I already cleaned this repo out. |
|
I'm concerned about this change; I think #467 (comment) is probably the right way. In #396 (comment) @vtjnash said
which sounds like we should only be closing the ones we create here. |
I haven't had time to read through all these threads, but will soon(TM). I think we can push these changes through as they mimic the existing functionality, then open an issue to discuss? |
|
Ok, that sounds fine to me |
|
bors r+ |
467: Always close the `response_stream` after `HTTP.request` r=mattBrzezinski a=nickrobinson251 - We need to explicitly close the `response_stream` (`HTTP.request` no longer closes it for us) in HTTP.jl v0.9.15+ (see JuliaWeb/HTTP.jl#752) - Since `close` is safe to call multiple times, this should be compatible with old HTTP.jl versions. - Should fix issue #466 (and JuliaCloud/AWSS3.jl#215) - Also since we're fixing this here, we can close JuliaWeb/HTTP.jl#772 ~TODO: add test... i just need to recreate the issue using AWS.jl explicitly (rather than AWSS3)~ done. Co-authored-by: Nick Robinson <nicholas.robinson@invenialabs.co.uk> Co-authored-by: Nick Robinson <npr251@gmail.com>
|
CI failed, but also threw
|
|
i don't understand bors -- is CI running, or...? |
|
bors r+ |
|
Personally, I think this should have been addressed by upper bounding HTTP.jl. That would have been a trivial change in comparison and would have given us more time to work out the details of this PR |
|
A fair point conceptually. Another good option might have been to revert the change to HTTP.jl and tag a release. |
|
Yeah, reverting the change to HTTP.jl would have been another option, but may have required more discussion. |
response_stream(
HTTP.requestno longer closes it for us)in HTTP.jl v0.9.15+ (see Do not call
close()on theresponse_streamJuliaWeb/HTTP.jl#752)closeis safe to call multiple times,this should be compatible with old HTTP.jl versions.
AWS._http_requestbroken when using HTTP.jl v0.9.15 #466 (ands3_get_filehangs (with HTTP 0.9.15) AWSS3.jl#215)TODO: add test... i just need to recreate the issue using AWS.jl explicitly (rather than AWSS3)done.