-
Notifications
You must be signed in to change notification settings - Fork 6.3k
8268294: Reusing HttpClient in a WebSocket.Listener hangs. #4506
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
Conversation
|
👋 Welcome back michaelm! A progress list of the required criteria for merging this PR into |
|
@Michael-Mc-Mahon The following label will be automatically applied to this pull request:
When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command. |
Webrevs
|
dfuch
left a comment
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.
Great fix and great test Michael.
I don't specially like the blind cast to HttpClientFacade - maybe we can revisit that later.
I have only one comment - about the use of Thread.sleep(3_000) in the test.
| WebSocketTest wsTest = new WebSocketTest(httpClient, args[0]); | ||
| HttpTest httpTest = new HttpTest(httpClient, args[1]); | ||
|
|
||
| AtomicReference<String> result = new AtomicReference<>("failed"); |
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.
Would it be possible to use a CountDownLatch - or a CompletableFuture instead of an atomic reference in order to replace the Thread.sleep(3_000) at line 44 with latch.await() or cf.join()?
The test would then fail in jtreg timeout without the fix, but would not have to wait for an arbitrary magic 3s delay if the fix is present (which might not be enough delay on slow machines with debug builds etc...)
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.
Good idea on the CF or latch. As regards the blind cast, I suppose I could test for it and if the type is different, leave the executor reference as null, which reverts current behavior, but I can't imagine a scenario where that would actually happen. If it did, would we want to revert the behavior, or fail visibly with CCE?
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 agree - I can't see how it could be something else than HttpClientFacade with the current implementation. Maybe just let's leave that up for later cleanup. What I had in mind was adding a static helper method somewhere on a public class in jdk.internal.net.http that would have access to the package private APIs - something like:
public static Executor getClientExecutor(HttpClient client) {
... and here we could do some switch depending on the concrete subclass of HttpClient
we're dealing with ...
}
But I don't see an obvious home for such a method - so maybe we should leave this for a later cleanup.
|
@Michael-Mc-Mahon This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be: You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 2 new commits pushed to the
Please see this link for an up-to-date comparison between the source branch of this pull request and the ➡️ To integrate this PR with the above commit message to the |
|
/integrate |
|
Going to push as commit 2d088fa.
Your commit was automatically rebased without conflicts. |
|
@Michael-Mc-Mahon Pushed as commit 2d088fa. 💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored. |
Hi,
This fixes a problem where the listener methods of a WebSocket client were being invoked by the Selector manager thread, which is problematic, because if the implementation of any of these methods tries to do any blocking work, this impacts other http activity, and if the blocking work is a http client call, then a hang can result. The fix makes the HttpClient's executor available to WebSocketImpl and that is used to offload the listener invocations.
The fix also adds a more comprehensive test framework for WebSockets (in WebSocketServer). Up to now we just had a limited server side in the tests that can only do the handshake. This change adds an API and implementation for server's to receive websocket messages and send replies back to clients. To implement this, the server hooks into WebSocket's Frame, MessageEncoder and MessageDecoder classes. Therefore, the implementations of these classes had to be modified to allow for the encoding of server generated messages and the decoding of client generated messages. The only difference between client and server in this respect relates to payload masking which is only done for messages sent from client to server.
There's a couple of warts that I wasn't sure what to do with. 1) There is already a copy of the Frame implementation class in the test hierarchy. I presume this is used by other tests, but that implementation is not used by this change. 2) The WebSocketServer is based on the existing DummyWebSocketServer class which is used by other tests. I can't see any easy way to refactor/combine these implementations.
Thanks,
Michael.
Progress
Issue
Reviewers
Reviewing
Using
gitCheckout this PR locally:
$ git fetch https://git.openjdk.java.net/jdk pull/4506/head:pull/4506$ git checkout pull/4506Update a local copy of the PR:
$ git checkout pull/4506$ git pull https://git.openjdk.java.net/jdk pull/4506/headUsing Skara CLI tools
Checkout this PR locally:
$ git pr checkout 4506View PR using the GUI difftool:
$ git pr show -t 4506Using diff file
Download this PR as a diff file:
https://git.openjdk.java.net/jdk/pull/4506.diff