-
Notifications
You must be signed in to change notification settings - Fork 6.1k
8329829: HttpClient: Add a BodyPublishers.ofFileChannel method #26155
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
base: master
Are you sure you want to change the base?
Conversation
👋 Welcome back vyazici! A progress list of the required criteria for merging this PR into |
❗ This change is not yet ready to be integrated. |
Webrevs
|
src/java.net.http/share/classes/jdk/internal/net/http/RequestPublishers.java
Outdated
Show resolved
Hide resolved
src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java
Outdated
Show resolved
Hide resolved
src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java
Outdated
Show resolved
Hide resolved
Co-authored-by: Daniel Fuchs <67001856+dfuch@users.noreply.github.com>
src/java.net.http/share/classes/jdk/internal/net/http/RequestPublishers.java
Show resolved
Hide resolved
src/java.net.http/share/classes/jdk/internal/net/http/RequestPublishers.java
Outdated
Show resolved
Hide resolved
src/java.net.http/share/classes/jdk/internal/net/http/RequestPublishers.java
Outdated
Show resolved
Hide resolved
src/java.net.http/share/classes/jdk/internal/net/http/RequestPublishers.java
Show resolved
Hide resolved
src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java
Outdated
Show resolved
Hide resolved
src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java
Outdated
Show resolved
Hide resolved
@@ -720,6 +719,34 @@ public static BodyPublisher ofFile(Path path) throws FileNotFoundException { | |||
return RequestPublishers.FilePublisher.create(path); | |||
} | |||
|
|||
/** | |||
* {@return a request body publisher whose body is the {@code length} |
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 think some of the text in this javadoc would need changes/clarifications. I haven't added any review comments for it yet and will come to it later once we have settled on the rest of the review.
Thank you for the updates - the implementation changes look good to me. I'll focus on the test and the API javadoc text next. |
// Verifying the client failure | ||
LOGGER.log("Verifying the client failure"); | ||
Exception requestFailure = assertThrows(ExecutionException.class, () -> responseFutureRef.get().get()); | ||
assertInstanceOf(UncheckedIOException.class, requestFailure.getCause()); |
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 think the application should be receiving a IOException
(both for send() and sendAsync()) instead of a UncheckedIOException
.
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 IOE
thrown is wrapped by an UncheckedIOE
in FileChannelIterator::next
, which overrides Iterator::next
and that does not allow a throws
in the next()
footprint. Would you mind elaborating on your remark, please?
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.
Hello Volkan, the specification of HttpClient.send(...)
(and sendAsync()) is that it throws a checked IOException
. So any other exceptions that we throw internally (like this one) need to be converted to an IOException
when it reaches the application code.
We have code in HttpClientImpl.send(...)
which currently does instanceof checks against these exceptions and converts them to an IOException
. I'm guessing your test is currently passing, which suggests to me that sendAsync()
is propagating a UncheckedIOException
to the application code. Would it be possible to tweak the test a bit to replace that call of sendAsync()
with a send()
(even if those tweaked changes cannot be pushed to this PR) and see what gets propagated? I suspect it would be IOException
.
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've confirmed that updating the test to use send()
results in IOE
getting received. I have not updated the PR in this direction, since it adds more boilerplate, and I read your lines as, not a change, but a research request – let me know if you meant otherwise.
the specification of
HttpClient.send(...)
(andsendAsync()
) is that it throws a checkedIOException
HttpClient::send
has the following Javadoc:
* @throws IOException if an I/O error occurs when sending or receiving, or
* the client has {@linkplain ##closing shut down}
* @throws InterruptedException ...
* @throws IllegalArgumentException ...
whereas ::sendAsync
Javadoc has no details regarding I/O failures. Do you think the fact that sendAsync()
does not have a to-IOException
-translation is an oversight that should be improved, or an intentional slack for the implementation?
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.
Hello Volkan,
whereas ::sendAsync Javadoc has no details regarding I/O failures.
The sendAsync()
has the same specification about IOException as that of send()
. It says:
* <p> The returned completable future completes exceptionally with:
* <ul>
* <li>{@link IOException} - if an I/O error occurs when sending or receiving,
* or the client has {@linkplain ##closing shut down}.</li>
* </ul>
Do you think the fact that sendAsync() does not have a to-IOException-translation is an oversight that should be improved, or an intentional slack for the implementation?
My expectation is that both send() and sendAsync() should propagate the same exception to the application (of course for sendAsync() it would be propagated as a cause in the ExecutionException
). So this is a surprise to me that we aren't currently doing that. We'll need inputs from Daniel (@dfuch) and Michael (@Michael-Mc-Mahon) whether this is intentional or an oversight.
I have not updated the PR in this direction, since it adds more boilerplate, and I read your lines as, not a change, but a research request
Yes, that's OK. Having said that, if it's easy to add a test which uses send() and causes an IOException (due to the FileChannel being closed mid way, for example), then it would be a good thing since that will then bring in the necessary coverage for the exception propagation for that method too.
Adds a new
ofFileChannel(FileChannel channel, long offset, long length)
method tojava.net.HttpRequest.BodyPublishers
to provide anHttpClient
publisher to upload a certain region of a file. The new publisher does not modify the state of the passedFileChannel
, streams the file channel bytes as it publishes (i.e., avoids reading the entire file into the memory), and can be leveraged to implement sliced uploads. As noted in the Javadoc:Implementation notes
FileChannel
is preferred over{Readable,Seekable}ByteChannel
, since the latter does not provide a positional read without modifying the state of theFileChannel
, which is necessary to use a singleFileChannel
instance to implement sliced uploads.ofFileChannel(FileChannel,long,long)
is preferred overofPath(Path,long,long)
to avoid overloading the maximum file descriptor limit of the platform.Progress
Issue
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/26155/head:pull/26155
$ git checkout pull/26155
Update a local copy of the PR:
$ git checkout pull/26155
$ git pull https://git.openjdk.org/jdk.git pull/26155/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 26155
View PR using the GUI difftool:
$ git pr show -t 26155
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/26155.diff
Using Webrev
Link to Webrev Comment