Motivation
Documentation is nice, and we can help support users by providing useful
clear docs.
Modifications
Add Docc to 5.6 and later builds
Make sure symbol references work
Add overview docs
Result
Nice rendering docs
Motivation:
Right now we're playing a little fast and loose with the lifetimes of
the sec_protocol_metadata_t. As a practical matter it is highly likely
that this is owned (and so kept alive by) the NWConnection, but rather
than risk that we should tighten up the lifetime management.
Modifications:
Use withExtendedLifetime to extend the lifetime.
Result:
Better lifetime management.
Motivation:
We no longer support Cocoapods and `swift package generate-xcodeproj` is
deprecated, so we shouldn't advertise their usage in the README.
Modifications:
Remove Cocoapods and `swift package generate-xcodeproj` sections from
the README.
Result:
More up-to-date README
Motivation:
When we're waiting for connectivity, the user might tell us that they
aren't interested in waiting. In that case we take advantage of the
signal and close early.
However, the code as-written had a bug: we didn't care whether the user
told us they _didn't_ want to wait, or they _did_: we just closed
because they had an opinion! That's no good! We should only close if
they don't want to wait.
Modifications:
- Only close if the user doesn't want to wait.
- Add tests
Result:
We won't close if users don't want us to.
Motivation:
Private Relay kicks in to secure unencrypted data transfers, and
connections to port 80 are a good signal. As a result, the current
construction of this test will invoke Private Relay and attempt to route
over it.
While Private Relay is in beta this is a bad outcome, as it risks
causing bugs in unusual network scenarios. So let's tell Private Relay
we don't need it.
Modifications:
Pretend we're gonna connect to 443 instead.
Result:
More reliable test.
Motivation:
To workaround https://github.com/apple/swift-nio/issues/2073 we must
list all transitive dependencies when building podspecs.
Modifications:
- Include transitive dependencies in the build_podspec script
- The list of dependencies was generated using
the `list_transitive_dependencies.py` from the NIO repo.
Result:
Podspec generation script includes transitive dependencies.
As outlined in a [Swift forums post in November ’21](https://forums.swift.org/t/swiftnio-swift-version-support/53232), SwiftNIO will only support the latest non-patch Swift release and the 2 immediately prior non-patch versions.
- drop support for Swift 5.2 and 5.3.
- update CI for Swift 5.4 to run on bionic instead of focal to ensure that we still test bionic.
- add a CI job for Swift 5.7
Motivation:
When a task is scheduled using a `DispatchTimerSource` on a `NIOTSEventLoop`
the source is retain via a callback on the promise associated with the
scheduled task. This stops the source from deinit'd before the task is
run. However, the callback being added is an implementation details of
`Scheduled` and the retain cycle is incidental.
If that detail chnaged (such as in
https://github.com/apple/swift-nio/pull/2011) then tasks may not run and
the promise could be leaked.
Modifications:
- Explicitly add a retain cycle between the future and the timer source
which is broken by the promise being completed and callbacks run.
Result:
The timer source is kept alive until the event fires.
Motivation:
With NIO 2.32.0 we broke the core NIO module up into modules that split
apart the POSIX layer and the core abstractions. As a result, this
package no longer needs to express a hard dependency on the POSIX layer.
Modifications:
- Rewrote imports of NIO to NIOCore.
- Added NIOEmbedded imports where necessary in tests.
- Note that the main package still _depends_ on NIO, which is necessary
for backwards-compatibility reasons. This dependency is unused.
Result:
No need to use NIOPosix.
Motivation:
The event loop state is not protected for access on different threads.
This means it must only be accessed from the task queue.
Modifications:
Move check for event loop shutdown into taskQueue
Result:
Event Loop state only accessed from the task queue.
Motivation:
`removeHandlers(channel:)` was deprecated in NIO 2.32.0.
Modifications:
- Raise minimum required NIO version to 2.32.0
- Use `removeHandlers(pipeline:)`
Result:
We don't use deprecated API.
Motivation:
NIO 2.27.0 added optional support for synchronous channel options.
NIOTSListenerChannel and NIOTSConnectionChannel should support this.
Modifications:
- Add synchronous options for NIOTSConnectionChannel and
NIOTSListenerChannel
- Avoid an allocation in 'getOption' for each channel if the caller is
already on the right event loop by using 'makeSucceededFuture'
- Remove a no longer used internal function and an already dead private
helper
Result:
- Support for sync options and fewer allocations
Motivation:
We shouldn't crash if the user gives us a bad port.
Modifications:
- Check the ports are in-band before we move on.
Result:
We won't crash.
Motivation:
xcodebuild complains during Cocapods validation (which fails as a
result) about a redundant availability check. It's redundant because for
watchOS the availability guard on the outer scope has the same
conditions (for other platforms the conditions are tighter in the
inner scope). We never hit this before because we only recently added
watchOS to the supported platforms for Cocapods.
Modifications:
- Remove a redundant availability check
Result:
- Cocapods can validate without error
Motivation:
The zero-length writes handler will crash if it receives channelInactive
before channelActive. Sadly, that's totally possible if a channel is
closed from the connect promise.
Modifications:
- Tone back the preconditions a bit.
- Add a test that triggers this path.
Result:
Channel handler behaves better on early close
Motivation:
We support watchOS 6+ with SwiftNIO Transport Services; as such we should
include watchOS as a deployment target for our CocoaPods.
Modifications:
- Add a watchOS deployment target to `build_podspecs.sh`
Result:
Users can deploy to watchOS 6+ with CocoaPods.
Motivation:
Network.framework will crash when we attempt to connect to the host
string "". That's not ideal, so we should detect that case and avoid it.
Modifications:
- Add code to detect the empty host string.
Result:
No crashes when accidentally connecting to "".
Motivation:
Docker shell was incorrectly using the swift-nio docker image
rather than the swift-nio-transport-services one.
Modifications:
Change docker compose file to use the correct image.
Result:
Correct image will be used for docker shell.
Motivation:
It's important that transport-services compiles and does nothing
on linux so it can be used in builds which just do the right thing
on all platforms.
Modifications:
Add basic docker-compose files based on those from swift-nio
Result:
It's possible to run docker on this repo to run the tests.
Motivation:
The NetworkFramework directly supports the concept of allowLocalEndPointReuse. Currently to get through the nio system, this is mapped to the SO_REUSEADDR option.
Now there is a shorthand option for this, it is sad to map from allowLocalEndPointReuse to SO_REUSEADDR and back again.
Modifications:
Add a new NIOTS channel option for this setting.
Set the underlying based on any of new setting, reuseAddr or reusePort.
Add a override to interpret the shorthand option directly into the new option.
Add shorthand options for client with tests of equivalence to long options.
Result:
Behaviour is identical but we can feel happier that the option mapping is less confusing.
Motivation:
In a patch where we added some metadata options, we accidentally set the
availability wrong. This is a compile-time error, so we broke watchOS
compilation.
Modifications:
Update the availability of some types on watchOS.
Result:
Users can build on watchOS again.
Motivation:
The build_podspec.sh script generates a podspec which requires exact
versions of its dependencies. This very quickly turns into unresolvable
dependency graphs.
Modifications:
NIO version passed to script must be in the format MAJOR.MINOR
Podspec dependencies are now '>= MAJOR.MINOR', '< MAJOR+1'
Result:
Looser version requirements for podspecs
Motivation:
On Apple's devices it is considered a best practice to wait for network
connectivity in cases when a connection request cannot immediately be
satisfied, rather than erroring out. This reflects the dynamic and fluid
network environment on Apple devices, with their many network interfaces
and complex interactions between radios, VPNs, and network devices.
While NIOTS supports this model of interaction (and indeed uses it out
of the box), and supports configuring it (by setting
`NIOTSChannelOptions.waitForActivity`), a key pillar is missing:
observability. Right now we don't actually _tell_ the user when we're
waiting for connectivity. This makes it difficult to act on this
information.
Modifications:
- Added a user event, `NIOTSNetworkEvents.WaitingForConnectivity` that
is fired when connectivity could not be established, but the situation
may change in future.
Result:
Our users can tell their users when they're waiting for something!
* Initial draft implementation of new channel options for NWConnection.currentPath, metadata for a given NWProtocol, establishment report and data transfer report. Add a new error for not existing connection. Add tests for all of these. The data transfer report option has to be implemented in another way, as the collection of the final data transfer report does not seem very straightforward.
* Fix incorrect available attributes. Make the Value of NIOTSEstablishmentReportOption an EventLoopFuture returning an optional report. Move handling of NIOTSEstablishmentReportOption and NIOTSDataTransferReportOption to getOption0. Remove nwConnection0().
* Use full type on currentPath too.
* Add a DispatchQueue to do collect of the pending data transfer report, use a DispatchGroup to wait for completion of report collection. Remove redundant attribute. Fix nits related to spacing and file header.
* Fix available attributes for tests too.
Motivation:
It's not obvious what happens when `childChannelInitializer` returns a
failed future. See https://github.com/apple/swift-nio/pull/1516
Modifications:
Add a note to the `childChannelInitializer` documentation.
Result:
Better docs.
Motivation:
We have a weird availability model for NIOTS since we can build it even
if Network.framework isn't available: we don't document this anywhere.
Modifications:
Explain supported platform model in the README.
Result:
Better documentation.
Motivation:
See apple/swift-nio#1508 for rationale
Modifications:
Provides implementations of `preconditionInEventLoop(_:file:line:)` and `preconditionNotInEventLoop(_:file:line:)`.
Result:
NIOTSEventLoop will now use dispatchPrecondition(condition:) for the in/not in preconditions instead of relying on the default implementation, yielding improved correctness.
Motivation:
Today, we just expect the ELGs passed to the bootstraps to be the
correct ones, if not, we crash.
Modifications:
Offer an alternative validatingGroup: init that just returns nil
if the ELGs are of the wrong types.
Result:
Easier to work with multi-stack systems for example when the user might
pass an ELG for either NIO on Sockets or NIO on Network.framework.
This is the NIOTS companion for https://github.com/apple/swift-nio/pull/1464
Add filter removing empty writes to remedy a bug in Network Framework. This is a work in progress, after some initial discussions and suggestions by @weissi.
Motivation:
There is a known bug in Network Framework affecting iOS devices, which will stall a TCP connection after an empty, zero length write. This bug is not found in Network Framework on MacOS. While the bug fix will be rolled out in future versions of iOS it may take some time. Also, to better support the current and older versions of iOS where the bug remains, @weissi suggested to add a ChannelOutboundHandler, that filters out empty writes.
Modifications:
Add a FilterEmptyWritesHandler, which on affected iOS versions can be added by default to all Channels.
Unit tests for all additions and modifications.
Result:
With this workaround NIOTransportServices can support all iOS versions with Network Framework.