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

Reduce probability of LB selecting an unusable connection #948

Merged
merged 1 commit into from
Feb 28, 2020

Conversation

NiteshKant
Copy link
Collaborator

Motivation

NettyChannelPublisher closes the connection if it sees a cancel() before all data for the current Subscriber is read. However, the client layer makes the connection eligible for selection by load balancer if it sees a cancel() being unaware that the connection MAY be eventually closed by the transport. This creates a race condition where load balancer may select a connection which is going to be closed.

Modification

Pessimistically assume that if we see a cancel() for a request, transport will close the connection so force close the connection. This is pessimistic because it may so happen that completion of read is racing with the cancel and transport may see read completion before cancel and hence not close the connection. At the client layer (where we control LB selection eligibility), it is impossible to discern whether transport will close the connection or not so the safest option is to assume closure. This reduces the possibility of selecting an unusable connection hence the pains associated with debugging those situations at the cost of closing the connection.
For H2, this will be a stream, which is cheap to close but for H1 this will close the actual connection.

Result

Reduce possibility of selecting an unusable connection. As cancel() is not the only reason for closure, we still have the case where a connection can be selected only to be closed later but we reduce that probability with this change.

__Motivation__

`NettyChannelPublisher` closes the connection if it sees a `cancel()` before all data for the current `Subscriber` is read. However, the client layer makes the connection eligible for selection by load balancer if it sees a `cancel()` being unaware that the connection MAY be eventually closed by the transport. This creates a race condition where load balancer may select a connection which is going to be closed.

__Modification__

Pessimistically assume that if we see a `cancel()` for a request, transport will close the connection so force close the connection. This is pessimistic because it may so happen that completion of read is racing with the cancel and transport may see read completion before cancel and hence not close the connection. At the client layer (where we control LB selection eligibility), it is impossible to discern whether transport will close the connection or not so the safest option is to assume closure. This reduces the possibility of selecting an unusable connection hence the pains associated with debugging those situations at the cost of closing the connection.
For H2, this will be a stream, which is cheap to close but for H1 this will close the actual connection.

__Result__

Reduce possibility of selecting an unusable connection. As `cancel()` is not the only reason for closure, we still have the case where a connection can be selected only to be closed later but we reduce that probability with this change.
import static io.servicetalk.concurrent.api.SourceAdapters.toSource;
import static io.servicetalk.http.api.HttpEventKey.MAX_CONCURRENCY;

final class ConcurrentRequestsHttpConnectionFilter implements FilterableStreamingHttpConnection {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This was dead code.

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.

2 participants