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

Tolerate new request after connection error happened #688

Merged
merged 2 commits into from May 17, 2023

Conversation

dnadoba
Copy link
Collaborator

@dnadoba dnadoba commented May 15, 2023

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

  • change all preconditionFailures in HTTP1ConnectionStateMachine.swift to fatalErrors to see the message in release builds
  • tolerate .closing in addition to .closed in runNewRequest
  • add test which previously crashed

Result

AHC no longer crashes in the race condition described above.

@dnadoba dnadoba added the 🔼 needs-minor-version-bump For PRs that when merged cause a bump of the minor version, ie. 1.x.0 -> 1.(x+1).0 label May 15, 2023
Comment on lines -185 to 196
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.
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 is the actual bug fix.

Copy link
Collaborator

@Lukasa Lukasa left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Member

@fabianfett fabianfett left a comment

Choose a reason for hiding this comment

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

LGTM. Great change!

@Lukasa Lukasa merged commit 78db67e into swift-server:main May 17, 2023
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🔼 needs-minor-version-bump For PRs that when merged cause a bump of the minor version, ie. 1.x.0 -> 1.(x+1).0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants