-
Notifications
You must be signed in to change notification settings - Fork 123
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
Tolerate new request after connection error happened #688
Conversation
case .initialized, .closing, .inRequest: | ||
case .initialized, .inRequest: | ||
// These states are unreachable as the connection pool state machine has put the | ||
// connection into these states. In other words the connection pool state machine must | ||
// be aware about these states before the connection itself. For this reason the | ||
// connection pool state machine must not send a new request to the connection, if the | ||
// connection is `.initialized`, `.closing` or `.inRequest` | ||
preconditionFailure("Invalid state: \(self.state)") | ||
fatalError("Invalid state: \(self.state)") | ||
|
||
case .closed: | ||
case .closing, .closed: | ||
// The remote may have closed the connection and the connection pool state machine | ||
// was not updated yet because of a race condition. New request vs. marking connection | ||
// as closed. |
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 is the actual bug fix.
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
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. Great change!
Motivation
A connection and the connection pool may be on different threads and therefore run concurrently. If a connection error happens the connections closes itself and notifies the pool about it. While this is happening the connection pool could already decide to run a new connection on the closing connection. We need to tolerate this happening. We already partially do but only if the connection is fully closed but not currently still closing.
Result
preconditionFailure
s inHTTP1ConnectionStateMachine.swift
tofatalError
s to see the message in release builds.closing
in addition to.closed
inrunNewRequest
Result
AHC no longer crashes in the race condition described above.