Commit Graph
29 Commits
Author SHA1 Message Date
Rick Newton-Rogers 56724a2b6d NIOAsyncTestingChannel local/remote addrs on EmbeddedChannelCore (#3442)
### Motivation:

`NIOAsyncTestingChannel` stored its `localAddress` and `remoteAddress`
in a locked storage on itself for thread safety, however in doing so
left us open to bugs because a handler grabbing the addresses of the
context had no visibility of the values.

### Modifications:

Reach into `EmbeddedChannelCore` for the addresses instead of storing
them on the `NIOAsyncTestinghannel`. I also considered a delegate
approach where the `EmbeddedChannelCore` could offload the
responsibility for storing the values back to the
`NIOAsyncTestingChannel` but it was complicated and of questionable
value.

### Result:

* The correct address values are seen no matter how they are obtained.
* We probably take a performance hit locking the values in this way but
this is testing code so probably not the end of the world.
2025-11-11 15:08:15 +00:00
Fabian Fett 6c114e3c62 Update CI scripts for 6.2 (#3374)
Replaces: #3373
2025-09-19 13:55:48 +01:00
Cory Benfield c9e2ac115f Adjust for SendableMetatype (#3266)
Motivation

With the introduction of isolated conformances, it has become necessary
to start managing the use of metatypes for some of our protocols. In
general, we don't want to force the relevant protocols to only be
conformed in non-isolated forms. Instead, we just want to make the
specific APIs non-usable.

Modifications

- Add shims for SendableMetatype that only use it when it is available.
- Require SendableMetatype where needed, gated by @preconcurrency.

Result

We continue to be safe.
2025-06-13 09:12:25 +01:00
Rick Newton-Rogers 57658e12ff Drop Swift 5.9 (#3228)
Motivation:

Swift 5.9 is no longer supported, we should bump the tools version and
remove it from our CI.

Modifications:

* Bump the Swift tools version to Swift 5.10
* Remove Swift 5.9 jobs where appropriate in main.yml, pull_request.yml

Result:

Code reflects our support window.
2025-05-07 12:24:44 +00:00
Rick Newton-Rogers b8c446368d Add and enable Swift 6.1 workflows (#3196)
Add and enable Swift 6.1 workflows

### Motivation:

Swift 6.1 has been released, we should add it to our CI coverage.

### Modifications:

* Update `appe/swift-nio/scripts/generate_matrix.sh`
* Update reusable adopters of `swift_test_matrix.yml`
* Update end-user adopter workflows of `swift_test_matrix.yml`
  * Copy over test flags from Swift 6.0 jobs

### Result:

NIO tests against Swift 6.1 in CI and downstream repositories can
opt-in.

(Successful CI run with the workflows modified to use the changes on
this branch
https://github.com/apple/swift-nio/actions/runs/14400598096?pr=3196)
2025-04-11 13:45:49 +01:00
Rick Newton-Rogers 8a475ed378 Update nightly main benchmark thresholds (#3187)
### Motivation:

Nightly main benchmarks have improved allocations, we should lock in the
win.

### Modifications:

Update nightly main benchmark thresholds

### Result:

Thresholds reflect gains, passing CI.
2025-04-08 11:20:14 +01:00
Rick Newton-Rogers 26d40ebbda Delete Thresholds/nightly-6.1 symlinks (#3133)
Following on from https://github.com/apple/swift-nio/pull/3126 delete
`Benchmarks/Thresholds/nightly-6.1` and
`IntegrationTests/tests_04_performance/Thresholds/nightly-6.1.json`
which is no longer needed now that the shared benchmarks workflow has
been updated.
2025-03-07 12:09:53 +00:00
Rick Newton-Rogers 517dccac42 rename nightly 6 1 to nightly next (#3126)
Use nightly_next as swift version

see https://github.com/apple/swift-nio/pull/3122

Motivation:
To not have to rename threshold directories when the nightly branch
changes.

Modifications:
* Use nightly_next as swift version in the matrix generation script
which
is picked up by the benchmark script.
* Move nightly-next thresholds and add legacy symlink

Result:

Benchmark thresholds will attempt to find directories named
nightly_next, not nightly_6_1.
2025-03-04 09:37:47 +00:00
Cory Benfield 0c547a717c Fix the HappyEyeballsResolver and core Bootstraps under strict concurrency (#3062)
### Motivation:

The HappyEyeballsResolver, being an old part of our stack, has a lot of
code in it that fails to pass strict concurrency checking. That's deeply
suboptimal.

### Modifications:

- Clean up the happy eyeballs resolver under strict concurrency
- Further cleanups to the bootstraps

### Result:

Another step taken on the road to strict concurrency.
2025-01-23 13:22:18 +00:00
Rick Newton-Rogers 9336e1f259 more 6.0 nightly to 6.1 nightly CI changes (#3078)
### Motivation:

Some changes were missed in #3076, passing through parameters for the
new 6.1 version.

### Modifications:

Pass through more parameters, clean up misleading comments.

### Result:

6.1 nightly runs will be more like 6.0 nightly runs were
2025-01-22 13:38:02 +00:00
Rick Newton-Rogers 27c839f470 GetaddrinfoResolver succeeds futures on eventLoop (#3042)
### Motivation:

`testClientBindWorksOnSocketsBoundToEitherIPv4OrIPv6Only` would fail
sometimes leaking the IPv4 promise in `GetaddrinfoResolver`

`HappyEyeballsConnector` returns the connection when it resolves either
IPv4 of IPv6. It uses the `GetaddrinfoResolver` which holds a promise
for each of the IPv4 and IPv6 resolution; when one is completed the
connection will be returned and it is possible to start tearing down the
test and shutting down the event loop before the other is completed and
we leak the promise.

### Modifications:

Complete both futures on the event loop rather than the dispatch queue.

### Result:

The futures are completed in the same event loop tick meaning that we
cannot continue execution and leak one.
2025-01-08 16:33:33 +00:00
Rick Newton-Rogers 19da487ef2 clean up 5.8 thresholds (#2932)
clean up 5.8 thresholds

### Motivation:

GitHub's merge retained files we don't need now we've dropped 5.8

### Modifications:

remove 5.8 thresholds

### Result:

no unused files
2024-10-17 15:46:55 +02:00
Franz Busch 2fe3d92cf5 Drop support for Swift 5.8 (#2924)
# Motivation

We only support the last three Swift released versions which are at this
time 5.9, 5.10 and 6.

# Modification

This PR drops anything related to Swift 5.8.

# Result

Version support aligned.
2024-10-17 12:22:10 +00:00
Rick Newton-Rogers 06c16b1a26 Add future wait benchmark to catch memory leaks (#2931)
### Motivation:

In the past we introduced a memory leak around the creation of and
waiting on futures - we should protect against leaks in this fundamental
operation.

### Modifications:

Add a new benchmark which would have failed with the previous bug

### Result:

Regression protection for this type of memory leak.
2024-10-17 13:03:52 +01:00
Franz Busch 290b349e2c [CI] Fix python lint (#2925)
# Motivation

Fix the python lint check.

# Modification

This PR fixes all the warnings related to the new python lint check.

# Result

Only green CI.
2024-10-17 09:57:40 +00:00
Franz Busch e59009da9b Align benchmark scaling and minimum samples (#2839)
# Motivation

We want to have an aligned strategy across all of our benchmarks in how
we use the scaling factor and samples.

# Modification

This PR makes sure that any inner loop is scaled by the scaling factor.
Moreover, we want to run more than 1 iteration. To do this we set an
almost infinite maximum duration and a maximum iteration count.

# Result

More consistent benchmarks
2024-08-15 09:51:52 +00:00
George Barnett 223b0e8eac Add manual control to NIOLockedValueBox (#2786)
Motivation:

NIOLockedValueBox has a 'safer' API than NIOLock as it only provides
scoped access to its boxed value. NIOLock requires users to only access
protected state while the lock is acquired. As such NIOLockedValueBox
should be preferred where possible. However, there are cases where
manual control must be used (such as storing a continuation) and users
must use a NIOLock for this.

There are two downsides to this:

1. All other access to the protected state must use the NIOLock API
   putting the onus on the developer to only access the protected state
   while the lock is held.
2. NIOLock can't store its protected state inline which typically
   results in users storing it on a class.

Modifications:

- Add an 'unsafe' view to NIOLockedValueBox which allows users to
  manually control the lock and access its protected state
- Update NIOAsyncWriter and NIOThrowingAsyncSequenceProducer to use NIOLockedValueBox

Result:

- Safer locking API is used in more places
- Fewer allocations
2024-07-18 01:16:59 -07:00
Franz Busch 8a69bd9d88 [GHA] Cxx interoperability compatibility and integration tests check (#2790)
# Motivation

Another reusable check is to make sure that all library products of a package are successfully building when consumed from a module that has Cxx interoperability enabled. Another check that's missing is running the integration tests.

# Modification

This PR adds two new checks to the reusable workflow. One to check for Cxx interoperability compatibility and another one to run the integration tests. I also fixed a misalgined name for the nightly benchmarks.

# Result

This should be one of the last reusable workflow checks.
2024-07-16 01:22:04 -07:00
George Barnett 0f4c110bd7 Combine the two NIOAsyncChannel channel handlers (#2779)
Motivation:

The NIOAsyncChannel allocates 12 times on init. 4 of these allocations
come from creating two channel handlers and two channel handler
contexts. There's no inherent reason that these channel handlers can't
be combined to eliminate two allocations (one handler and one context).

Modifications:

- Combine `NIOAsyncChannelInboundStreamChannelHandler` and
  `NIOAsyncChannelOutboundWriterHandler` into a single
  `NIOAsyncChannelHandler`. Most of this was straightforward as only a
  few handler operations were duplicated across both.
- Add a 'NIOAsyncChannelHandlerWriterDelegate' in place of the
  'NIOAsyncChannelOutboundWriterHandler.Delegate'. One knock on from
  this is that the new delegate stores callbacks rather than the
  concrete type of the handler. This is necessary to prevent the
  generics from the new channel handler bubbling up to the outbound
  writer (which would break API and be somewhat odd).

Result:

Fewer allocations
2024-07-12 01:02:04 -07:00
Franz Busch 86316020a5 [GHA] Benchmark job (#2780) 2024-07-11 03:23:24 -07:00
George Barnett 4d87167a42 Add benchmark for creating NIOAsyncChannel (#2774)
Motivation:

NIOAsyncChannel has a number of allocs associated with it. We should
have a benchmark which tracks the number of allocs.

Modifications:

- Add NIOCoreBenchmarks with a single benchmark

Result:

Better insight
2024-07-10 10:34:04 +01:00
George Barnett cc158ec6c7 Raise minimum Swift version to 5.8 (#2675) 2024-03-11 08:47:57 +00:00
Franz Busch 826fce4fdb Fix NIOAsyncChannel allocation benchmarks (#2622)
# Motivation
We had to disable the benchmarks since they regressed without us noticing and they appear to be flaky.

# Modification
This PR fixes the allocation regression and tries to re-enable them.
2024-01-12 14:23:54 +00:00
David Nadoba 23e995b3af Set SWIFT_VERSION environment variable to resolve to the correct benchmarks thresholds path (#2613)
* Set `SWIFT_VERSION` environment variable to resolve to the correct benchmarks thresholds path

* mallocs have increased

* update benchmark results manually

* update thresholds again

* disable flaky benchmark
2023-12-22 11:07:35 +01:00
Franz Busch 2910d6b203 Call NIOAsyncWriterSinkDelegate outside of the lock (#2547)
* Call `NIOAsyncWriterSinkDelegate` outside of the lock

# Motivation
The current `NIOAsyncWriter` implementation expects that the delegate is called while holding the lock to avoid reentrancy issues. However, this prevents us from executing the delegate calls directly on the `EventLoop` if we are on it already.

# Modification
This moves all of the delegate calls outside of the locks and adds protection against reentrancy into the state machine.

# Result
Less allocations.

Clarify the reentrancy problems in docs and protect against them in the writer

* Code review
2023-10-12 08:33:51 -07:00
Franz Busch 94cc73dfbb Improve performance of NIOAsyncChannel (#2539)
* Implement fast paths for `AsyncChannelInboundStreamChannelHandler`

* Add `_TinyArray` from `swift-certificates`

* Implement single element customization point in `NIOAsyncChannelOutboundWriterHandler`

* Call the single element optimization more often and store suspended producers in `_TinyArray`.

* Update thresholds

* Fix compiler warning
2023-10-09 07:39:25 -07:00
Franz Busch c2d8eed7e6 Add customization point for scheduling ExecutorJobs on EventLoops (#2538)
# Motivation
Currently, the NIO's EventLoop conformance to the `SerialExecutor` protocol always uses `execute` to schedule the actual job. However, the closure for `execute` has to close over the job and the `EventLoop` itself; hence, it always allocates. Since jobs are a very fine grained object in Concurrency that are created a lot this lead to millions of allocations in even small benchmarks.

# Modification
This PR provides a customization point for `EventLoop`s to execute `ExecutorJob`s directly. For `SelectableEventLoop` we store a type erased `UnownedJob` in our `ScheduledTask` and just run it right away.

# Result
No more allocations when NIO's EL is used as a `SerialExecutor`.
2023-10-09 06:00:57 -07:00
Franz Busch 7a9d37ef49 Add NIOAsyncChannel benchmark (#2536)
# Motivation
We want to benchmark our `NIOAsyncChannel` to see how it compares to the synchronous implementation with `ChannelHandler`s

# Modification
This PR adds a new `TCPEchoAsyncChannel` benchmark that mimics the `TCPEcho` benchmark but uses our new async bridges.
Since Swift Concurrency, is normally using a global executor this benchmark would have quite high variation. To reduce this variant I introduced code to hook the global executor and set an `EventLoop` as the executor. In the future, if we get task executors we can change the code to us them instead.

# Result
New baseline benchmarks for the `NIOAsyncChannel`.
2023-10-09 10:45:00 +01:00
Franz Busch d782de84df Adopt package-benchmark (#2534)
# Motivation
We want to migrate our allocation and later on also our performance tests to use the `package-benchmark` plugin. This plugin makes writing benchmarks way easier than our current setup. Furthermore, debugging benchmarks is also possible from within Xcode now.

# Modification
This PR adds the setup for the benchmarking infrastructure and connects it with out

# Result
Allocations tests are more accessible and easier to iterate.
2023-10-08 13:31:22 -07:00