Added buffer pool to NIOTSConnectionChannel for reading messages.
### Motivation:
In order to avoid creating a new `ByteBuffer` for every single message
read from the channel, we decided to reuse the
`NIOPooledRecvBufferAllocator` type from NIOCore to leverage a pool of
buffers.
### Modifications:
Used the buffer allocation mechanism provided by the
`NIOPooledRecvBufferAllocator` to reuse and adapt previously created
receive buffers.
### Result:
Channel reads can now reuse previously created buffers, avoiding
unnecessary overhead by creating new buffers every single time.
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.
### Motivation:
The datagram-related types logically mirror the TCP-based ones
(`NIOTSDatagramListenerBootstrap` vs `NIOTSListenerBootstrap`;
`NIOTSListenerChannel` vs `NIOTSDatagramListenerChannel`;
`NIOTSDatagramChannel` vs `NIOTSDatagramConnectionChannel`;
`NIOTSDatagramBootstrap` vs `NIOTSConnectionBootstrap`).
However, some of the type names could more closely resemble their TCP
counterparts to make it easier to navigate the code/understand what
their purpose is.
Additionally, the docs for some of these types are wrong, as they've
been copy-pasted into the datagram versions without changes.
### Modifications:
There are separate commits for each of the following changes:
- Fix docs for `NIOTSDatagramListenerBootstrap` and rename the file to
match the type name.
- Rename `NIOTSDatagramConnectionChannelTests` to
`NIOTSDatagramBootstrapTests` (to match `NIOTSBootstrapTests`).
- Rename `NIOTSDatagramChannel` to `NIOTSDatagramConnectionChannel` (to
match `NIOTSConnectionChannel`)
- Fix docs for `NIOTSConnectionBootstrap`.
- Rename `NIOTSDatagramBootstrap` to `NIOTSDatagramConnectionBootstrap`
(to match `NIOTSConnectionBootstrap`). This one required a deprecate and
replace since it's a public type.
### Result:
Better docs and more consistency in our type names.
Allow users to provide a closure taking an `NWParameters` to customise
them before they're used to create `NWConnection`s.
### Motivation:
`NWParameters` are currently created using the provided TLS and UDP
options, and then passed over to new `NWConnection`s. However, there are
more ways in which `NWParameters` can be customised, so this new API
provides a way for users to do this.
### Modifications:
Introduce new `configureNWParameters` methods to the existing bootstraps
to allow configuring a closure for customising `NWParameters`.
### Result:
Users can now customise the `NWParameters` used to create new
`NWConnection`s.
Motivation:
Swift 6.1 has been released, we should add it to our CI coverage.
Modifications:
Add additional Swift 6.1 jobs where appropriate in main.yml,
pull_request.yml
Result:
Improved test coverage.
Current strict concurrency checks don't work consistently in Xcode. This
PR adds an additional flag (`-Xfrontend`) to our set of strict
concurrency flags to make sure nothing has been missed when building. It
also fixes an additional error uncovered after adding it.
Motivation:
* Improve test coverage
Modifications:
Enable macOS CI to be run on pull request commits and make the use of
the nightly runner pool for main.yml jobs explicit.
Result:
Improved test coverage.
Enable macOS CI on merge to main and daily timer
### Motivation:
* Improve test coverage
* Check test pass/fail status
* Monitor CI throughput
### Modifications:
Enable macOS CI to be run on all merges to main and on a daily timer.
### Result:
Improved test coverage run out-of-band at the moment so we can get a
feeling for if any changes need to be made in the repo or in the CI
pipelines to ensure timely and stable checks.
Motivation:
Dispatch wasn't imported in `NIOTSSingletons.swift` where `.default` was
used for the default QoS. This causes some build issues.
Modifications:
- Add missing Dispatch import
Result:
Fewer build issues
---------
Co-authored-by: Cory Benfield <lukasa@apple.com>
Enable MemberImportVisibility check on all targets. Use a standard
string header and footer to bracket the new block for ease of updating
in the future with scripts.
Remove the integration tests workflow from the main and scheduled jobs.
### Motivation:
There are no integration tests in this repository.
(see
https://github.com/apple/swift-nio-transport-services/actions/runs/11833082880)
### Modifications:
Remove the integration tests workflow from the main and scheduled jobs.
### Result:
No more scheduled run failures.
### Motivation:
* `main.yml` and `scheduled.yml` are mostly duplicative.
* Scheduled runs failed because of a deprecated reference to a Swift 5.8
pipeline
### Modifications:
* Unify `main.yml` and `scheduled.yml`
* Remove the reference to the 5.8 pipeline
### Result:
Working scheduled runs.
### Motivation:
To migrate to GitHub actions and centralised infrastructure.
### Modifications:
Changes of note:
* Adopt swift-format using rules from SwiftNIO. Modified so that it
ignores `NoAssignmentInExpressions` in some `XCTAssert` functions.
* Remove scripts and docker files which are no longer needed
### Result:
Feature parity with old CI.
Motivation:
Users are stuck with the hardcoded parameters for receiving data from a
connection.
Modifications:
- Add new options to `NIOTSChannelOptions` for configuring how to
receive data from a connection.
Result:
Users can configure how they receive data from a connection.
This reverts commit 40ffcdef46 in PR #209.
Unfortunately, Swift's behaviour around imports tends to be somewhat
"leaky". In this case, the leak is that the dependency on the
Package.swift allows downstream projects to import `NIOFoundationCompat`
without needing to actually specify the package dependency. This has
affected Hummingbird, which we noticed on our internal integration
testing functionality:
```
hummingbird/Sources/Hummingbird/Codable/JSON/JSONCoding.swift:18:8: error: no such module 'NIOFoundationCompat'
import NIOFoundationCompat
^
```
cc @Joannis @adam-fowler for the Hummingbird report.
Unfortunately, we can't make this change until we're willing to use a
semver major to achieve it. There may be some argument for doing that
now, as the semver major will be very cheap to adopt across the
ecosystem. But we'll need to do this in a considered way.
@Cyberbeni please feel free to reopen your PR targetting main, where we
can discuss whether this is worth issuing a semver major for.
Don't depend on NIOFoundationCompat in NIOTransportServices on Linux
### Motivation:
I'm trying to build a small utility tool based on mqtt-nio which depends
on NIOTransportServices. I noticed that NIOTransportServices depends on
NIOFoundationCompat on all platforms but only imports it where the
Network framework is available. Removing this dependency on non-Apple
platforms allows us to not import Foundations, significantly reducing
the size of the build product when using the Swift Static Linux SDK.
### Modifications:
This PR and a similar one to mqtt-nio.
### Result:
Hello world docker image depending on mqtt-nio went from 169MB to 85MB.
Motivation:
Swift Package Index builds our docs for us and will automatically insert
the dependency.
Modifications:
- Remove the docc-plugin dependency
Result:
Fewer dependencies
### Motivation:
Allow different devices to leverage the capabilities of Mutipath TCP
(MPTCP) to enhance the network reliability. Thanks to MPTCP, a
connection can for example automatically migrate to another interface if
it deteriorates on the first one. This can be especially interesting on
MacOS X and iOS, where devices may frequently benefit from multiple
interfaces (ethernet + Wi-Fi for Macs and Wi-fi + cellular for iOS).
Allowing developers to enable MPTCP on their connections seems thus like
a fine addition to this library.
### Modifications:
Added a function "withMultipath" on NIOTSConnectionBootstrap, that allow
to configure the type of service used for MPTCP (defaults to disabled).
This value will be stored in a field, and then propagated to the
underlying channel when the connect method will be called. Also updated
the parameters field of NIOTSConnectionChannel to set the
multipathServiceType accordingly.
### Result:
Users will now be able to easily enable Multipath TCP, allowing them to
benefit from seamless handover, interactive mode to automatically use
the lowest delay interface or aggregate mode to send data in parallel on
both interfaces.
Example:
```swift
let group = NIOTSEventLoopGroup()
defer {
try! group.syncShutdownGracefully()
}
let bootstrap = NIOTSConnectionBootstrap(group: group)
.withMultipath(.handover) // set handover mode
.channelInitializer { channel in
channel.pipeline.addHandler(MyChannelHandler())
}
try! bootstrap.connect(host: "example.org", port: 12345).wait()
/* the Channel is now connected */
```
Co-authored-by: Cory Benfield <lukasa@apple.com>
# Enhancement: Integration of Viability Handler in `Network.framework`
We have successfully integrated the `viabilityUpdateHandler` from
`Network.framework` into `NIOTransportServices`, enabling developers to
leverage the full potential of the `Network.framework` API.
This enhancement provides adopters with critical insights into the
viability of connections to remote endpoints. By being informed about
the current network status, developers can implement a more responsive
and adaptive approach to network behavior and conditions.
## Modifications
- Introduced two new methods along with corresponding calls to these
methods within the `Network.framework` handler.
- These handlers trigger the `NIO` *InboundEventsTriggered* method,
allowing consumers to respond to network changes effectively.
- Developed two structs within *NIOTSNetworkEvents* to accompany the
*InboundEventsTriggered* methods, ensuring seamless data transfer.
- Conformed these structs to Sendability for compatibility with the
required operating systems.
## Result
Clients can now receive viability events from `Network.framework`,
enhancing their ability to manage network connections dynamically
---------
Co-authored-by: George Barnett <gbarnett@apple.com>
Co-authored-by: Cory Benfield <lukasa@apple.com>
Motivation:
In some cases users may want to access APIs we haven't exposed
in NIOTransportServices. We should have a fallback that allows users
to do this.
Modifications:
- Add ChannelOptions for getting NWConnection and NWListener.
Result:
Users have an escape hatch
Motivation:
Looks like when we previously added syncOptions support to our
channels, we had a few issues. The listeners had code added, but
the code never worked. This is because the code was defined in
subclasses, but the protocol conformance comes from the parent class,
and that parent class did not have a customized protocol witness.
The datagram channel was also entirely missing its support.
Modifications:
- Added the missing unit tests for sync options.
- Added syncOptions to StateManagedListenerChannel base class.
- Added overrides to the listener subclasses.
- Added syncOptions to datagram channel
Result:
Sync options actually work across the board.
# Motivation
We missed a few availability guards in our tests which caused errors when compiling for older Darwin platforms.
# Modification
This PR adds the missing guards.
# Result
We should build on all supported platforms again
# Motivation
After the recent changes in NIO where we introduced the `executeThenClose` method on the `NIOAsyncChannel` our tests here became flaky since we were waiting for something to happen but potentially closed the client channels before we wrote out the data.
# Modification
This PR makes sure we are awaiting for the event in the `executeThenClose` scope; hence, making sure we are not closing the client channels too early.
# Result
Less flakey tests.
# Motivation
We missed a few availability guards in our tests which caused errors when compiling for older Darwin platforms. Additionally the latest NIO release deprecated a few APIs on `NIOAsyncChannel`.
# Modification
This PR adds the missing guards and fixes all of the deprecation warnings.
# Result
We should build on all supported platforms again
* Revert "Back out SPI(AsyncChannel) changes"
This reverts commit 33d2b2993f.
* Add new typed async bootstrap APIs back and drop SPI
# Motivation
We just merged the removal of the `AsyncChannel` SPI in NIO and can now add back the new APIs in transport services as well.
# Modification
This PR brings back the previous SPI and promotes it to API.
# Result
New typed async bootstraps API for `NIOTransportServices`.
* George review
* Fire the pipelines error caughted method when NWConnection's state changes to failed
* Added check if failed error is ChannelError.eof and added a unit test for forwarding failed connnection state errors
* Completing a promise for the error caught
* Fixed Typo
* Removed whitespace
* Binding the listener to port 0 and connecting to listerner's localAddress
Motivation:
Now that Swift 5.9 is GM we should update the supported versions and
remove 5.6
Modifications:
* Update `Package.swift`
* Delete the 5.6 docker compose file and make a 5.10 one
* Update docs
Result:
Remove support for Swift 5.6, add 5.10
Motivation:
There was a typo when setting the allowLocalEndpointReuse channel option, where it was cast to NIOTSEnablePeerToPeerOption.Value
instead of NIOTSAllowLocalEndpointReuse.Value. Both of these types are Bools, so this wouldn't cause any actual issues, this change
is to more to keep the code consistent, and reduce confusion for future contributors or others reading the code base.
Modifications:
This commit casts the allowLocalEndpointReuse property in StateManagedListenerChannel and StateManagedNWConnectionChannel.
Result:
The typo is fixed after this change.
Motivation:
The datagram tests use a handler which sets its event loop in
`channelRegistered`. A function on the handler is called which relies on
the EL being set. However, this can race: the function can be called
before `channelRegistered` is called.
Modifications:
- set the EL in `handlerAdded`
Result:
Fewer crashes
Motivation:
This change was made because UDP support was lacking on iOS. It's needed by my DNS client implementation, which I am in turn using for an iOS app I'm working on relying on SRV typed records.
Modifications:
Adds a NIOTSDatagramListenerBootstrap for making UDP services
Adds a NIOTSDatagramListenerChannel that accepts UDP connections
Adds a NIOTSDatagramChannel for UDP client connections
Adds a NIOTSDatagramBootstrap that can create a new UDP client
# Motivation
We want to release a new `NIOTS` version without the SPI changes for now.
# Modification
This PR backs out the new `NIOAsyncChannel` APIs.
# Result
No more SPI usage so we can safely release.
# Motivation
We had some breaking changes in the NIO AsyncChannel SPI which we have to adapt here.
# Modification
This PR updates to the latest AsyncChannel SPI
# Result
No more warnings and errors when building.
# Motivation
After my recent PR we failed to compile on 5.6 since the compiler isn't capable to infer the return type of one of the closures.
# Modification
This PR adds the closure's return type explicitly.
# Result
Compiling on 5.6 again
# Motivation
We introduced some breaking SPI(AsyncChannel) changes in NIO that we have to adopt here.
# Modification
This PR adopts the latest `NIOProtocolNegotiationResult` APIs. Additionally, it also drops all bind/connect methods on the bootstraps that are specific to protocol negotiation or `NIOAsyncChannel`.
# Result
Green CI on `main` and alignment between `NIOPosix` and `NIOTS.
# Motivation
We introduced a new configuration struct for `NIOAsyncChannel` to make handling and configuring it easier.
# Modification
This PR adopts the new APIs.
# Result
Less boilerplate in our bootstrap methods
* Extract the NWConnection code into StateManagedNWConnectionChannel
* Add a general setup for NWListener implementations
* Add support for UDPOptions as a NWOptionsProtocol type
* Complete the rebase to main
* Fix nits from PR review
* Clean up some of the invalid rebase
* Extract the NWConnection code into StateManagedNWConnectionChannel
* Process cory's feedback
* Remove dead code whose functionality is already handled by the helper protocol
* Make the address cache non-locked, because its lock has been moved to the accessors
* Move getting the Multipath option into the TCP channel, re-introduce the underscores to the addressCache properties
* Drop the umbrella import
---------
Co-authored-by: Cory Benfield <lukasa@apple.com>
* Async methods for `NIOTSListenerBootstrap` and `NIOTSConnectionBootstrap`
# Motivation
We want to support async bootstrapping with all our bootstraps.
# Modification
This PR adds support for the `NIOTSListenerBootstrap` and `NIOTSConnectionBootstrap`. It also adds the three variants of methods to it (abstract output, `NIOAsyncChannel` based and protocol negotiation based)
# Result
We now support asynchronous interaction with the `NIOTSListenerBootstrap` and `NIOTSConnectionBootstrap`
* Use protocolHandlers properly
* Update NIO version
* code review
* REview
* Doc indention