Skip to content

Retry on EPROTOTYPE on socket writes. - #1706

Merged
Lukasa merged 1 commit into
apple:mainfrom
Lukasa:cb-eprototype
Dec 17, 2020
Merged

Retry on EPROTOTYPE on socket writes.#1706
Lukasa merged 1 commit into
apple:mainfrom
Lukasa:cb-eprototype

Conversation

@Lukasa

@Lukasa Lukasa commented Dec 17, 2020

Copy link
Copy Markdown
Contributor

Motivation:

When writing to a network socket on Apple platforms it is possible to
see EPROTOTYPE returned as an error. This is an undocumented and
special-case error code that appears to be associated with socket
shutdown, and so can fire when writing to a socket that is being shut
down by the other side. This should not be fired into the pipeline but
instead should be retried.

Modifications:

  • Retry EPROTOTYPE errors on socket write methods.
  • Add an (unfortunately) probabilistic test bed.

Result:

Should avoid weird error cases.
Resolves swift-server/async-http-client#322.

Comment thread Sources/NIO/System.swift Outdated
case (EWOULDBLOCK, true, _):
return .wouldBlock(0)
#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
case (EPROTOTYPE, _, eprototypeWorkaround):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is this meant to be true rather than eprototypeWorkaround?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Uhhhhh yes.

Motivation:

When writing to a network socket on Apple platforms it is possible to
see EPROTOTYPE returned as an error. This is an undocumented and
special-case error code that appears to be associated with socket
shutdown, and so can fire when writing to a socket that is being shut
down by the other side. This should not be fired into the pipeline but
instead should be retried.

Modifications:

- Retry EPROTOTYPE errors on socket write methods.
- Add an (unfortunately) probabilistic test bed.

Result:

Should avoid weird error cases.

@glbrntt glbrntt left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nice one!

@saroar

saroar commented Dec 17, 2020

Copy link
Copy Markdown

@Lukasa @glbrntt thanks 🧘🏻‍♂️🙏🏾

@Lukasa
Lukasa merged commit 4853e91 into apple:main Dec 17, 2020
@Lukasa
Lukasa deleted the cb-eprototype branch December 17, 2020 17:45
Lukasa added a commit to Lukasa/swift-nio that referenced this pull request Dec 18, 2020
This reverts commit 4853e91.

While we have been able to observe the effect that this change was
trying to workaround, the change seems to interact poorly with a
different issue in Big Sur that can cause EPROTOTYPE to be consistently
emitted during socket writes on otherwise connected sockets. This would
change a connection-terminating error into a 100% CPU spin that rendered
the event loop entirely useless: a substantial regression.

For this reason, we should back this out until the issue is better
characterised.
Lukasa added a commit that referenced this pull request Dec 18, 2020
This reverts commit 4853e91.

While we have been able to observe the effect that this change was
trying to workaround, the change seems to interact poorly with a
different issue in Big Sur that can cause EPROTOTYPE to be consistently
emitted during socket writes on otherwise connected sockets. This would
change a connection-terminating error into a 100% CPU spin that rendered
the event loop entirely useless: a substantial regression.

For this reason, we should back this out until the issue is better
characterised.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🔨 semver/patch No public API change.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

write(descriptor:pointer:size:): Protocol wrong type for socket (errno: 41)

3 participants