-
Notifications
You must be signed in to change notification settings - Fork 62
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Always close the response_stream
after HTTP.request
#467
Always close the response_stream
after HTTP.request
#467
Conversation
- 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 #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 <[email protected]>
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 |
@@ -213,6 +213,8 @@ function _http_request(http_backend::HTTPBackend, request::Request) | |||
isa(e, Base.IOError) || | |||
(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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.IOError
earlier. E.g. only close if it was opened internally.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, maybe it should be reverted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, left a couple comments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 <[email protected]> Co-authored-by: Nick Robinson <[email protected]>
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.request
no longer closes it for us)in HTTP.jl v0.9.15+ (see Do not call
close()
on theresponse_stream
JuliaWeb/HTTP.jl#752)close
is safe to call multiple times,this should be compatible with old HTTP.jl versions.
AWS._http_request
broken when using HTTP.jl v0.9.15 #466 (ands3_get_file
hangs (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.