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

Retain a ref to NIOAsyncWriter until channel active #2703

Merged
merged 2 commits into from
Apr 22, 2024

Conversation

glbrntt
Copy link
Contributor

@glbrntt glbrntt commented Apr 19, 2024

Motivation:

NIOAsyncChannel requires users to explicitly close it, this is typically done by calling executeThenClose. If a NIOAsyncChannel isn't closed then its outbound writer will hit a precondition failure on deinit. Not calling executeThenClose is a programmer error.

However there are some sharp edges: if NIO never returns the NIOAsyncChannel to the caller (e.g. if a connect attempt fails) then nothing will finish the writer and precondition will fail in the deinit. Working around this from a user perspective is non-obvious and requires keep tracking of all NIOAsyncChannels created from a connect attempt and closing the unused ones.

We still want to maintain the precondition when users don't close the channel, one way of achieving this is by defining a point in time at which NIO hands responsibility of the channel to the user.

Modifications:

  • Retain the writer in the outbound writer handler until channel active
  • On successful connect attempts, the channel becomes active and the connected channel is returned to the caller.
  • On failed attempts channel active isn't called so the writer is retained until the handler is removed from the pipeline at which point it is finished.

Result:

Failed connect attempts don't result in precondition failures when using NIOAsyncChannel.

Motivation:

NIOAsyncChannel requires users to explicitly close it, this is typically
done by calling `executeThenClose`. If a `NIOAsyncChannel` isn't closed
then its outbound writer will hit a precondition failure on `deinit`.
Not calling `executeThenClose` is a programmer error.

However there are some sharp edges: if NIO never returns the
`NIOAsyncChannel` to the caller (e.g. if a connect attempt fails) then
nothing will finish the writer and precondition will fail in the deinit.
Working around this from a user perspective is non-obvious and requires
keep tracking of all `NIOAsyncChannel`s created from a connect attempt
and closing the unused ones.

We still want to maintain the precondition when users don't close the
channel, one way of achieving this is by defining a point in time at
which NIO hands responsibility of the channel to the user.

Modifications:

- Retain the writer in the outbound writer handler until channel active
- On successful connect attempts, the channel becomes active and the
  connected channel is returned to the caller.
- On failed attempts channel active isn't called so the writer is
  retained until the handler is removed from the pipeline at which point it is
  finished.

Result:

Failed connect attempts don't result in precondition failures when using
NIOAsyncChannel.
@glbrntt glbrntt added the semver/patch No public API change. label Apr 19, 2024
@glbrntt
Copy link
Contributor Author

glbrntt commented Apr 19, 2024

Hmm, CI is failing to install jemalloc

08:56:25 10.53 E: Failed to fetch http://archive.ubuntu.com/ubuntu/pool/universe/j/jemalloc/libjemalloc2_5.2.1-4ubuntu1_amd64.deb  rename failed, No such file or directory (/var/cache/apt/archives/partial/libjemalloc2_5.2.1-4ubuntu1_amd64.deb -> /var/cache/apt/archives/libjemalloc2_5.2.1-4ubuntu1_amd64.deb).
08:56:25 10.53 E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?
08:56:25 ------
08:56:25 Dockerfile:23
08:56:25 --------------------
08:56:25   21 |     
08:56:25   22 |     # install jemalloc for running allocation benchmarks
08:56:25   23 | >>> RUN apt-get update & apt-get install -y libjemalloc-dev
08:56:25   24 |     
08:56:25   25 |     # tools
08:56:25 --------------------
08:56:25 ERROR: failed to solve: process "/bin/sh -c apt-get update & apt-get install -y libjemalloc-dev" did not complete successfully: exit code: 100

@glbrntt
Copy link
Contributor Author

glbrntt commented Apr 19, 2024

@swift-server-bot test this please

@Lukasa
Copy link
Contributor

Lukasa commented Apr 19, 2024

I'm happy with this, but would like JW to review.

@glbrntt glbrntt requested a review from weissi April 19, 2024 08:30
Copy link
Member

@FranzBusch FranzBusch left a comment

Choose a reason for hiding this comment

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

Thanks for working on this! This seems like a good targeted fix here and for the connect case makes total sense to me.

@glbrntt
Copy link
Contributor Author

glbrntt commented Apr 19, 2024

Now we have a fun mixture of failures unrelated to the changes...

Swift 5.9 and 5.10 are failing some datagram tests:

09:24:27 Test Case 'DatagramChannelTests.testSetGetEcnNotificationOption' started at 2024-04-19 08:24:27.687
09:24:27 /swift-nio/Tests/NIOPosixTests/DatagramChannelTests.swift:660: error: DatagramChannelTests.testSetGetEcnNotificationOption : XCTAssertNoThrow failed: threw error "unknown(host: "::1", port: 0)" -

and

09:24:27 Test Case 'DatagramChannelTests.testSetGetPktInfoOption' started at 2024-04-19 08:24:27.693
09:24:27 /swift-nio/Tests/NIOPosixTests/DatagramChannelTests.swift:829: error: DatagramChannelTests.testSetGetPktInfoOption : XCTAssertNoThrow failed: threw error "unknown(host: "::1", port: 0)" -

Swift 5.9 cxx interop is failing to establish connections to archive.ubuntu.com to install various dependencies:

09:25:39 85.82 E: Failed to fetch http://archive.ubuntu.com/ubuntu/pool/main/n/netcat-openbsd/netcat-openbsd_1.218-4ubuntu1_amd64.deb  Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4000:1::19). - connect (101: Network is unreachable) Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4002:1::101). - connect (101: Network is unreachable) Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4002:1::103). - connect (101: Network is unreachable) Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4002:1::102). - connect (101: Network is unreachable) Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4000:1::16). - connect (101: Network is unreachable)
09:25:39 85.82 E: Failed to fetch http://archive.ubuntu.com/ubuntu/pool/main/l/lmdb/liblmdb0_0.9.24-1build2_amd64.deb  Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4000:1::19). - connect (101: Network is unreachable) Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4002:1::101). - connect (101: Network is unreachable) Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4002:1::103). - connect (101: Network is unreachable) Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4002:1::102). - connect (101: Network is unreachable) Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4000:1::16). - connect (101: Network is unreachable)
09:25:39 85.82 E: Failed to fetch http://archive.ubuntu.com/ubuntu/pool/main/libm/libmaxminddb/libmaxminddb0_1.5.2-1build2_amd64.deb  Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4000:1::19). - connect (101: Network is unreachable) Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4002:1::101). - connect (101: Network is unreachable) Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4002:1::103). - connect (101: Network is unreachable) Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4002:1::102). - connect (101: Network is unreachable) Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4000:1::16). - connect (101: Network is unreachable)
09:25:39 85.82 E: Failed to fetch http://archive.ubuntu.com/ubuntu/pool/main/l/lsof/lsof_4.93.2%2bdfsg-1.1build2_amd64.deb  Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4000:1::19). - connect (101: Network is unreachable) Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4002:1::101). - connect (101: Network is unreachable) Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4002:1::103). - connect (101: Network is unreachable) Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4002:1::102). - connect (101: Network is unreachable) Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4000:1::16). - connect (101: Network is unreachable)
09:25:39 85.82 E: Failed to fetch http://archive.ubuntu.com/ubuntu/pool/main/libo/libonig/libonig5_6.9.7.1-2build1_amd64.deb  Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4000:1::19). - connect (101: Network is unreachable) Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4002:1::101). - connect (101: Network is unreachable) Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4002:1::103). - connect (101: Network is unreachable) Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4002:1::102). - connect (101: Network is unreachable) Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4000:1::16). - connect (101: Network is unreachable)
09:25:39 85.82 E: Failed to fetch http://archive.ubuntu.com/ubuntu/pool/main/j/jq/libjq1_1.6-2.1ubuntu3_amd64.deb  Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4000:1::19). - connect (101: Network is unreachable) Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4002:1::101). - connect (101: Network is unreachable) Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4002:1::103). - connect (101: Network is unreachable) Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4002:1::102). - connect (101: Network is unreachable) Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4000:1::16). - connect (101: Network is unreachable)
09:25:39 85.82 E: Failed to fetch http://archive.ubuntu.com/ubuntu/pool/main/j/jq/jq_1.6-2.1ubuntu3_amd64.deb  Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4000:1::19). - connect (101: Network is unreachable) Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4002:1::101). - connect (101: Network is unreachable) Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4002:1::103). - connect (101: Network is unreachable) Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4002:1::102). - connect (101: Network is unreachable) Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4000:1::16). - connect (101: Network is unreachable)
09:25:39 85.82 E: Failed to fetch http://archive.ubuntu.com/ubuntu/pool/main/n/net-tools/net-tools_1.60%2bgit20181103.0eebece-1ubuntu5_amd64.deb  Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4000:1::19). - connect (101: Network is unreachable) Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4002:1::101). - connect (101: Network is unreachable) Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4002:1::103). - connect (101: Network is unreachable) Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4002:1::102). - connect (101: Network is unreachable) Cannot initiate the connection to archive.ubuntu.com:80 (2620:2d:4000:1::16). - connect (101: Network is unreachable)
09:25:39 85.82 E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?
09:25:39 ------
09:25:39 Dockerfile:17
09:25:39 --------------------
09:25:39   15 |     # dependencies
09:25:39   16 |     RUN apt-get update && apt-get install -y wget
09:25:39   17 | >>> RUN apt-get update && apt-get install -y lsof dnsutils netcat-openbsd net-tools curl jq # used by integration tests
09:25:39   18 |     
09:25:39   19 |     # ruby
09:25:39 --------------------
09:25:39 ERROR: failed to solve: process "/bin/sh -c apt-get update && apt-get install -y lsof dnsutils netcat-openbsd net-tools curl jq # used by integration tests" did not complete successfully: exit code: 100

@glbrntt
Copy link
Contributor Author

glbrntt commented Apr 19, 2024

@glbrntt
Copy link
Contributor Author

glbrntt commented Apr 19, 2024

@swift-server-bot test this please

Copy link
Member

@weissi weissi left a comment

Choose a reason for hiding this comment

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

Perfect, thank you!

@glbrntt glbrntt enabled auto-merge (squash) April 22, 2024 08:06
@glbrntt
Copy link
Contributor Author

glbrntt commented Apr 22, 2024

@swift-server-bot test this please

@glbrntt glbrntt merged commit 359c461 into apple:main Apr 22, 2024
8 of 9 checks passed
@glbrntt glbrntt deleted the keep-writer-alive-until-active branch April 22, 2024 11:50
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.

4 participants