Skip to content
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

Issue #3379 - Add tracking of WebSocket Sessions to various WebSocket Container APIs #3383

Merged

Conversation

joakime
Copy link
Contributor

@joakime joakime commented Feb 21, 2019

#3379

  • Jetty WebSocket API now tracks Sessions and will close them on lifecycle stop
  • Javax WebSocket API now tracks Sessions and will close them on lifecycle stop
  • Adding Jetty WebSocket tests for proper close / session tracking

Signed-off-by: Joakim Erdfelt joakim@erdfelt.com

@joakime
Copy link
Contributor Author

joakime commented Feb 21, 2019

@lachlan-roberts with these additions, the testcases from jetty-9.4.x related to session tracking and proper close behavior at the API level is now present in this PR.
If you'll note, there's a bunch of close test cases that result in no close event at the application level.

Copy link
Contributor

@lachlan-roberts lachlan-roberts left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it seems like lots of these tests are just failing because they are outdated or testing the wrong thing, but some of them have also picked up some problems with the jetty-websocket implementation, perhaps most of these tests deserve a separate PR

client.setIdleTimeout(Duration.ofMillis(timeout));

ClientOpenSessionTracker clientSessionTracker = new ClientOpenSessionTracker(1);
clientSessionTracker.addTo(client);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So here to set a Connection.Listener we add the ClientOpenSessionTracker as a bean to the the WebSocketClient. But to successfully add the connection listener we need to set the Connection.Listener beans on the WebSocketCoreClient which is what we use to set the listeners on the WebSocketConnection in ClientUpgradeRequest.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, that's correct.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe all the Connection.Listener beans could be added to the WebSocketCoreClient on the connect method of the WebSocketClient?

// Verify that server socket got close event
AbstractCloseEndpoint serverEndpoint = serverEndpointCreator.pollLastCreated();
assertThat("Fast Close Latch", serverEndpoint.closeLatch.await(5, SECONDS), is(true));
assertThat("Fast Close.statusCode", serverEndpoint.closeStatusCode, is(StatusCode.ABNORMAL));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this expecting ABNORMAL close status, the server sends receives NORMAL close and this is received by the client at line 146, what event is expected to happen to cause the abnormal close

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this testcase, during the server onOpen() it issued a session.close().
Since the server's onOpen() never finished successfully, it the websocket connection was never opened for read on the server side, so it cannot read the response from the client. Hence the ABNORMAL closure.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is closing in onOpen abnormal? I can imagine services that in onOpen send a few messages and then immediately do a normal close and then return. I think that is normal!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

closing in onOpen is abnormal & wasClean==false.
this is because the close handshake cannot be completed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the close handshake can be completed, we send the close frame, we return from onWebSocketConnect the onOpen callback is succeeded, so we can now read frames, we read the close response which is normal status code

session = futSession.get(5, SECONDS);

// Verify that client got close
clientEndpoint.assertReceivedCloseEvent(5000, is(StatusCode.NORMAL), containsString(""));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reason should be "FastCloseServer"

session = futSession.get(5, SECONDS);

// Verify that client got close indicating SERVER_ERROR
clientEndpoint.assertReceivedCloseEvent(5000, is(StatusCode.SERVER_ERROR), containsString("Intentional FastFail"));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the message given to WebSocketException created at line 153 of JettyWebSocketFrameHandler.onOpen() is too long to fit in a close frame so the "Intentional FastFail" part is trimmed out

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Throwable.getMessage() is all that should be in the close reason.
If there is no Throwable.getMessage() (empty or null) then use the Throwable.getClass().getName().

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The @OnError gets the entire stacktrace anyway, so there's no purpose for the going nuts with the reason phrase.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using .getSimpleName() instead leaves enough room for the exception message, maybe that would be better

but the same change should be made in the JavaxWebSocketFrameHandler as well to keep it consistent


// Verify that server socket got close event
AbstractCloseEndpoint serverEndpoint = serverEndpointCreator.pollLastCreated();
serverEndpoint.assertReceivedCloseEvent(5000, is(StatusCode.SERVER_ERROR), containsString("Intentional FastFail"));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed line 180 to use containsString("") to reach this line.

This is failing due to a timeout on the closeLatch, the problem is that in JettyWebSocketFrameHandler the closeHandle is only invoked when a close frame is received, this is incorrect and should be instead invoked in the onClosed(CloseStatus, Callback) method

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this failed for a different reason than above so its not the same, this is due to a problem with the implementation of the JettyWebSocketFrameHandler, and its probably the reason why a lot of the tests are failing

@lachlan-roberts
Copy link
Contributor

@joakime did you want me to make the changes to fix this up
i would need to pull your changes and start a separate PR as i cant commit into this branch

… Container APIs

+ Jetty WebSocket API now tracks Sessions and will close them on
  lifecycle stop
+ Javax WebSocket API now tracks Sessions and will close them on
  lifecycle stop
+ Adding Jetty WebSocket tests for proper close / session tracking
+ Disabling tests that need triage

Signed-off-by: Joakim Erdfelt <joakim.erdfelt@gmail.com>
@joakime joakime force-pushed the jetty-10-issue-3379-websocket-session-tracking branch from 0502e48 to d8a9f26 Compare February 27, 2019 21:27
@joakime
Copy link
Contributor Author

joakime commented Feb 27, 2019

@lachlan-roberts i've @Disabled those tests we can triage those separately, as these are carryovers from the jetty-9.4.x to jetty-10.0.x merge (that this PR is handling)

@joakime joakime merged commit 936b438 into jetty-10.0.x Feb 27, 2019
@joakime joakime deleted the jetty-10-issue-3379-websocket-session-tracking branch February 27, 2019 21:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants