-
Notifications
You must be signed in to change notification settings - Fork 182
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
Mark HTTP/2 connection as closing on exception caught #2686
Conversation
CI shows that |
Motivation: Similar to apple#2675, `H2ParentConnectionContext.AbstractH2ParentConnection` should mark the `Channel` as closing on `exceptionCaught`. If there is no active `Subscriber`, it should enforce channel closure using `ChannelCloseUtils`. In case users don't have offloading, there is a risk to retry on the same IO thread. We should notify `LoadBalancer` that this connection is closing to avoid retrying on the same connection. Modifications: - Invoke `parentContext.notifyOnClosing()` inside `exceptionCaught` before notifying `transportError` and failing subscriber; - Close the h2 channel if there is no active `Subscriber` to consume the error; - Remove `H2ParentConnectionContext.notifyOnClosingImpl()` that does not seem required anymore; - Enhance `ConnectionClosedAfterIoExceptionTest` to make sure we fail only the first connect attempt, we capture `RetryableException`s, and capture the callers stack trace if `client.request(...)` fails; Result: Retries always select a different connection if existing connection observes an exception. Fixes apple#2685.
7e718c0
to
66c080f
Compare
* This method is required to access notifyOnClosing() from AbstractH2ParentConnection, because usage of | ||
* {@code parentContext.notifyOnClosing()} directly triggers {@link java.lang.IllegalAccessError}. | ||
*/ | ||
private void notifyOnClosingImpl() { |
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.
Removal of this method was the cause for H2PriorKnowledgeFeatureParityTest > serverGracefulClose
failures 🤦
I'm not sure why Intellij IDEA or javac could not catch this as a problem.
java.lang.BootstrapMethodError: java.lang.IllegalAccessError: tried to access method io.servicetalk.transport.netty.internal.NettyChannelListenableAsyncCloseable.notifyOnClosing()V from class io.servicetalk.http.netty.H2ParentConnectionContext$AbstractH2ParentConnection
at io.servicetalk.http.netty.H2ParentConnectionContext$AbstractH2ParentConnection.channelRead(H2ParentConnectionContext.java:291) ~[servicetalk-http-netty-0.42.39-SNAPSHOT.jar:?]
servicetalk-http-netty/src/main/java/io/servicetalk/http/netty/H2ParentConnectionContext.java
Show resolved
Hide resolved
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 (but you may want another pair of eyes who is more familiar with the H2 intrinsic behavior)
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.
quick peek, 1 question, lgtm
cause = wrapIfNecessary(cause); | ||
if (observer != NoopConnectionObserver.INSTANCE) { |
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 assume this is done at a higher level 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.
It will be done a couple lines below. Either tryFailSubscriber
or ChannelCloseUtils
will assign a connection error before closing the channel.
Motivation:
Similar to #2675,
H2ParentConnectionContext.AbstractH2ParentConnection
should mark theChannel
as closing onexceptionCaught
. If there is no activeSubscriber
, it should enforce channel closure usingChannelCloseUtils
.In case users don't have offloading, there is a risk to retry on the same IO thread. We should notify
LoadBalancer
that this connection is closing to avoid retrying on the same connection.Modifications:
parentContext.notifyOnClosingImpl()
insideexceptionCaught
before notifyingtransportError
and failing subscriber;Subscriber
to consume the error;H2ParentConnectionContext.hasSubscriber()
that does not seem required anymore;ConnectionClosedAfterIoExceptionTest
to make sure we fail only the first connect attempt, we captureRetryableException
s, and capture the callers stack trace ifclient.request(...)
fails;Result:
Retries always select a different connection if existing connection observes an exception.
Fixes #2685.