-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
Fixes #11016 - Jetty 12 IllegalStateException when stopping Server wi… #11017
Fixes #11016 - Jetty 12 IllegalStateException when stopping Server wi… #11017
Conversation
…th pending requests * Made ServletChannel error handling more robust. A failure in error handling is now remembered so that the Handler callback can be failed later. * Avoid failing the Handler callback from ServletChannel.abort(), as it is too early: should be failed when processing the TERMINATED state, similarly to when it is succeeded. * Removed dead code from HttpConnection.SendCallback.reset(), since response is always non-null. Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
…ed(). This may run the ErrorHandler twice when using ee10. Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
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.
Mostly just more comments/javadoc needed... but I think there may be a problem with
jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletChannel.java
Show resolved
Hide resolved
@@ -292,19 +293,13 @@ public String getStatusString() | |||
} | |||
} | |||
|
|||
public boolean completeResponse() | |||
public Throwable completeResponse() |
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 boolean return was giving protection against calling this method twice.
So either, there is a possibility that we will call it twice, in which case we still need the protection....
OR we will never call it twice, so instead we should throw ISE if we are ever called with it is already in COMPLETED state.
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.
This method is only called once because it is protected by the ServletChannel
state machine.
From ServletChannel.handle()
, we end up in the TERMINATED
state where we call onCompleted()
that calls this method.
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.
So can we have an assert (or ISE) if it is already in COMPLETED state
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.
Not sure what you refer to, as there are many COMPLETED states?
If you refer to _outputState
it can also be ABORTED.
I feel like we don't need this extra assert, as we just want to make the transition OPEN -> COMPLETED.
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.
This method used to return a boolean that indicated if it had just transitioned from OPEN->COMPLETED. If it returned false, then the callback would not be completed.
Now it returns a throwable to say if there has been a failure, in which case the callback is failed. But it has lost the protection for multiple calls, so the callback might be called twice.
I understand that you know this cannot happen because of external factors.... that nothing in this method represents that invariant. It would be clearer if it had something like:
assert _failure != null || _outputState == OutputState.OPEN
If this assert does not hold, then this PR has changed behaviour in a non obvious way.
...e10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletChannelState.java
Show resolved
Hide resolved
...e10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletChannelState.java
Outdated
Show resolved
Hide resolved
...e10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletChannelState.java
Outdated
Show resolved
Hide resolved
...e10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletChannelState.java
Outdated
Show resolved
Hide resolved
…pended-request-ise'.
Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
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.
All good, but a couple of nigglets.
@@ -292,19 +293,13 @@ public String getStatusString() | |||
} | |||
} | |||
|
|||
public boolean completeResponse() | |||
public Throwable completeResponse() |
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.
So can we have an assert (or ISE) if it is already in COMPLETED state
@@ -735,10 +729,13 @@ public void onCompleted() | |||
_servletContextRequest.setAttribute(CustomRequestLog.LOG_DETAIL, logDetail); | |||
} | |||
|
|||
// Callback will either be succeeded here or failed in abort(). | |||
// Callback is completed here. |
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.
Can we say:
// Callback is completed here. | |
// Callback is only completed here. |
…pended-request-ise'. Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
@@ -292,19 +293,13 @@ public String getStatusString() | |||
} | |||
} | |||
|
|||
public boolean completeResponse() | |||
public Throwable completeResponse() |
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.
This method used to return a boolean that indicated if it had just transitioned from OPEN->COMPLETED. If it returned false, then the callback would not be completed.
Now it returns a throwable to say if there has been a failure, in which case the callback is failed. But it has lost the protection for multiple calls, so the callback might be called twice.
I understand that you know this cannot happen because of external factors.... that nothing in this method represents that invariant. It would be clearer if it had something like:
assert _failure != null || _outputState == OutputState.OPEN
If this assert does not hold, then this PR has changed behaviour in a non obvious way.
Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
…th pending requests