Commit Graph
50 Commits
Author SHA1 Message Date
Rick Newton-Rogers c51907a839 Enable strict concurrency checking for NIOTLS (#3112)
### Motivation:

To ensure NIOTLS concurrency safety.

### Modifications:

* Enable strict concurrency checking in the package manifest.
* Require `NegotiationResult` to be `Sendable`
* In `NIOTypedApplicationProtocolNegotiationHandler<NegotiationResult>`
the
result is used to fulfil promises and perform hops so we need it to be
sendable when accessed from these other concurrency domains.

### Result:

Builds will warn and CI will fail if regressions are introduced.
2025-02-07 16:52:40 +00:00
Johannes Weiss 6ba8f4f04a fix almost all Sendable warnings (#2994)
### Motivation:

Opening the `swift-nio` repository made me warning blind because there
were always so many trivially fixable warnings about things that were
correct but cannot be understood by the compiler.

### Modifications:

Fix all the sendable warnings that popped up, except for one test where
`NIOLockedValueBox<Thread?>` isn't sendable because `Foundation.Thread`
seemingly isn't `Sendable` which is odd. Guessing that'll be fixed on
their end.

### Result:

- Fewer warnings
- Less warning-blindness
- More checks
2024-11-25 17:56:44 +00:00
Cory Benfield 411c2c553c Handle Sendability of RemovableChannelHandler (#2953)
Motivation:

RemovableChannelHandlers have a large API surface in NIOCore. That API
surface is a bit awkward with regard to strict concurrency, and needs
some cleanup.

Modifications:

This patch adds some new API that is necessary to safely work with
RemovableChannelHandlers, deprecates some API that cannot plausibly be
used, and cleans up some other parts of the API.

Result:

Easier to work with RemovableChannelHandlers
2024-10-29 10:40:47 +00:00
Franz Busch c9756e1083 Adopt swift-format (#2794)
* Apply formatting

* Apply no block comments rule

* Apply OmitExplicitReturns

* Apple OnlyOneTrailingClosureArgument

* Apply NoAssignmentInExpressions

* Fix up DontRepeatTypeInStaticProperties lint errors

* Apply `OrderedImports`

* Apply `ReplaceForEachWithForLoop`

* format file

* Enable the formatting pipeline

* Adopt `AmbiguousTrailingClosureOverload`

* Fix license header

* Fix format check

* Fix `EndOfLineComment`

* Fix CI

* Adapt CI script to check if changes when running formatting

* Separate lint and format into to steps

* Fix format

* Adopt `UseEarlyExits`

* Revert "Adopt `UseEarlyExits`"

This reverts commit d1ac5bbe12.
2024-07-19 11:48:17 +02:00
Franz Busch f38b7fd38a Remove SPI from NIOAsyncChannel, new bootstrap methods, protocol negotiation and HTTP upgrade. (#2548)
# Motivation
Over the past months, we have been working on new async bridges to make using NIO's `Channel` from Swift Concurrency possible. Since this work was far reaching we have opted to land all of it as SPI. Now the time has come and we feel confident enough to make the SPI official API. This comes after testing the new APIs in various scenarios such as HTTP 1&2, HTTP upgrades, protocol negotiation and in benchmarks.

# Modification
This PR removes the SPI from the `NIOAsyncChannel`, the bootstrap methods, protocol negotiation and HTTP upgrade.

# Result
Everyone can use the our new APIs🚀
2023-10-17 14:14:02 +01:00
Franz Busch dda031625c Remove NIOProtocolNegotiationResult (#2554)
# Motivation
After playing around more with the new async bootstrap methods, I came to the conclusion that the `NIOProtocolNegotiationResult` isn't carrying its weight. The `NIOProtocolNegotiationResult` is a glorified `EventLoopFuture` with an easy way to recursively resolve nested futures. Furthermore, it forces any nested protocol negotiation to use the same generic type for the end result.

# Modification
This PR removes the `NIOProtocolNegotiationResult` and changes all the tests to be solely based on `EventLoopFuture`s.

# Result
Less code to support the async bootstrap and better composition of nested protocol negotiation handlers.
2023-10-16 13:10:29 +01:00
Franz Busch 37c1a793a4 Remove ProtocolNegotiationHandler protocol (#2519)
# Motivation
When we created the first round of new async bootstrap APIs we added a `ProtocolNegotiationHandler` protocol to identify handlers that are doing protocol negotiation. Since then, we have changed the way how the async bootstraps work and we no longer need this protocol.

# Modification
Remove the `ProtocolNegotiationHandler` protocol
2023-09-20 18:05:50 +01:00
Franz Busch cf281631ff Avoid using deinit to fulfil the protocol negotiation promise (#2497)
# Motivation

Fixes https://github.com/apple/swift-nio/issues/2494

# Modification
This PR avoids using `deinit` to fulfil the protocol negotiation promise and opts to trap instead when it is being accessed before the handler is added. This allows us to use `handlerAdded` and `handlerRemoved`.

# Result
No more `deinit` usage that can be observed.
2023-08-08 09:17:08 +01:00
Franz Busch 84540145ce Fix leaked promise in NIOTypedApplicationProtocolNegotiationHandler (#2489)
# Motivation
We sometimes leaked a promise in the `NIOTypedApplicationProtocolNegotiationHandler` when the handler was created and immediately deinited.

# Modification
This PR makes sure we always complete the negotiation promise of the handler.

# Result
No more leaked promises.
2023-08-02 11:34:59 +01:00
Franz Busch e5416f4039 Reduce the amount of bootstrap async methods (#2474)
# Motivation
When adding new async methods for all the bootstrap we had to create 3 sets of method for every bootstrap. This resulted in lots of code and only provided little benefit for users.

# Modification
This PR removes all bind/connect methods except the most generic ones. This leaves it up to the user to wrap their channels in a `NIOAsyncChannel` or to await the protocol negotiation result.

# Result
Less code to maintain on our side.
2023-07-21 11:50:42 +01:00
Franz Busch d836d6bef5 Add AsyncChannel based ServerBootstrap.bind() methods (#2403)
* Add `AsyncChannel` based `ServerBootstrap.bind()` methods

# Motivation
In my previous PR, we added a new async bridge from a NIO `Channel` to Swift Concurrency primitives in the from of the `NIOAsyncChannel`. This type alone is already helpful in bridging `Channel`s to Concurrency; however, it is hard to use since it requires to wrap the `Channel` at the right time otherwise we will drop reads. Furthermore, in the case of protocol negotiation this becomes even trickier since we need to wait until it finishes and then wrap the `Channel`.

# Modification
This PR introduces a few things:
1. New methods on the `ServerBootstrap` which allow the creation of `NIOAsyncChannel` based channels. This can be used in all cases where no protocol negotiation is involved.
2. A new protocol and type called `NIOProtocolNegotiationHandler` and `NIOProtocolNegotiationResult` which is used to identify channel handlers that are doing protocol negotiation.
3. New methods on the `ServerBootstrap` that are aware of protocol negotiation.

# Result
We can now easily and safely create new `AsyncChannel`s from the `ServerBootstrap`

* Code review

* Fix typo

* Fix up tests

* Stop finishing the writer when an error is caught

* Code review

* Fix up writer tests

* Introduce shared protocol negotiation handler state machine

* Correctly handle multi threaded event loops

* Adapt test to assert the channel was closed correctly.

* Code review
2023-04-26 07:17:07 -07:00
David Nadoba 6720612111 Drop Swift 5.5 (#2406)
* Drop Swift 5.5

* Use `swift-atomics` 1.1.0 with `Sendable` adoption
2023-04-17 08:40:35 +01:00
Franz Busch a2fd8ad077 Handle reentranct reads in ALPNHandler (#2402)
# Motivation
I spotted a bug in the ALPNHandler where it doesn't properly unbuffer reentrant reads. This can lead to dropped reads.

# Modification
Instead of buffering into an array we are now buffering into a Deque and unbuffer as long as there are reads in the Deque.

# Result
No more dropped reads.
2023-04-13 05:06:15 -07:00
David Nadoba 16b5b2b793 Replace NIOSendable with Sendable (#2291) 2022-10-13 15:56:27 +01:00
David Nadoba 1100054107 Functions passed to non-Sendable ChannelHandlers do *not* need to be Sendable (#2249) 2022-08-26 17:59:34 +02:00
David Nadoba e2c7fa4d4b Adopt Sendable in NIOTLS (#2202) 2022-06-21 14:13:06 +01:00
Cory BenfieldandGeorge Barnett 64285cbff2 Clean up dependencies and imports. (#1935)
Motivation:

As we've largely completed our move to split out our core abstractions,
we now have an opportunity to clean up our dependencies and imports. We
should arrange for everything to only import NIO if it actually needs
it, and to correctly express dependencies on NIOCore and NIOEmbedded
where they exist.

We aren't yet splitting out tests that only test functionality in
NIOCore, that will follow in a separate patch.

Modifications:

- Fixed up imports
- Made sure our protocols only require NIOCore.

Result:

Better expression of dependencies.

Co-authored-by: George Barnett <gbarnett@apple.com>
2021-08-12 13:49:46 +01:00
Fabian Fett 76b4637122 Make language more welcoming (#1728) 2021-01-21 12:45:46 +00:00
Johannes Weiss 74944a937d use Optional<T> instead of T? to workaround SR-11777 (#1252)
Motivation:

In Swift, writing

    var something: T?

    init() {
        self.something = someValue
    }

means that the compiler will first set `self.something` to `nil` and
then in the init override it with `self.someValue`
(https://bugs.swift.org/browse/SR-11777). Unfortunately, because of
https://bugs.swift.org/browse/SR-11768 , stored property initialisation
cannot be made `@inlinable` (short of using `@frozen` which isn't
available in Swift 5.0).

The combination of SR-11768 and SR-11777 leads to `var something: T?`
having much worse code than `var something: Optional<T>` iff the `init`
is `public` and `@inlinable`.

Modifications:

Change all `var something: T?` to `var something: Optional<T>`

Result:

Faster code, sad NIO developers.
2019-11-27 18:37:38 +00:00
Jake 84169468fc Add ApplicationProtocolNegotiationHandler init that takes a closure that receives the Channel (#1196)
Motivation:

Currently ApplicationProtocolNegotiationHandler accepts a closure that takes only one argument, the ALPN result. This forces the user to capture the Channel in the closure so that it can be mutated.

Modifications:

Add a new init which takes a closure that has both the result and the Channel as parameters. Modify the original init to call the new init (wrapping the passed in closure.)

Result:

New APNL init available that takes a 2 parameter closure. Original APNL init will now be a convenience init.
2019-10-28 17:23:19 +00:00
Johannes Weiss d55c582e5c improve documentation (#919)
Motivation:

Spotted a couple of issues with the documentation and fixed them.

Modifications:

- explicitly marked all `public class`es as `public final class` to get
  consistency in the Jazzy documentation.
- removed `public` extension methods of the `internal struct
  PriorityQueue` which Jazzy showed in the docs.
- improved the largely missing `EmbeddedChannel` and `EmbeddedEventLoop`
  documentation.
- clear up lies in the B2MD docs
- add some other missing docs

Result:

better docs makes happier users
2019-03-25 12:09:16 +02:00
Johannes Weiss a41280919e rename ctx to context (#842)
Motivation:

`ctx` was always an abbreviation was 'context` and in Swift we don't
really use abbreviations, so let's fix it.

Modifications:

- rename all instances of `ctx` to `context`

Result:

- fixes #483
2019-02-25 18:20:22 +00:00
Johannes Weiss ff31b3135d improve B2MD EOF handling (#831)
Motivation:

Previously B2MDs didn't really have defined semantics regarding EOFs and
we didn't tell them if there was an EOF. Also `decodeLast` was optional
and all that was bad.

Modifications:

- require `decodeLast`
- add a `seenEOF: Bool` parameter to `decodeLast` which tells the
  decoder if an EOF has been seen

Result:

- clearer semantics
- more information
2019-02-21 14:14:50 +00:00
Johannes Weiss 46ffd630de ChannelPipeline: addHandler and removeHandler instead of add/remove (#817)
Motivation:

- `ChannelPipeline.add(name:handler:...)` had a strange order of arguments
- `remove(handler:)` and `remove(ctx:)` both remove `ChannelHandler`s
  but they read like they remove different things

So let's just fix the argument order and name them `addHandler` and
`removeHandler` making clear what they do.

Modifications:

- rename all `ChannelPipeline.add(name:handler:...)`s to `ChannelPipeline.addHandler(_:name:...)`
- rename all `ChannelPipeline.remove(...)`s to `ChannelPipeline.removeHandler(...)`

Result:

more readable and consistent code
2019-02-21 11:46:54 +00:00
Johannes Weiss d938264fcb better ChannelHandler removal API (#767)
Motivation:

If ChannelHandler removal worked correctly, it was often either by
accident or by intricate knowledge about the implementation of the
ChannelHandler that is to be removed. Especially when it comes to
re-entrancy it mostly didn't work correctly.

Modifications:

- introduce a `RemovableChannelHandler` API
- raise allocation limit per HTTP connection by 1
  (https://bugs.swift.org/browse/SR-9905)

Result:

Make things work by contruction rather than accident
2019-02-12 11:27:48 +01:00
Johannes Weiss 95b290a51f use automatic Equatable conformances (#737)
Motivation:

No code is the best code, let's have the compiler generate more
Equatable instances for us.

Modifications:

remove some hand-written Equatable conformances

Result:

less code, possibly fewer bugs
2019-01-07 11:52:22 +00:00
Johannes Weiss 684cad331c EventLoopFuture: use Result type (#734)
Motivation:

Now that the stdlib has introduced the Result type, we can use it in the
implementation (and the whenComplete) function of EventLoopFuture

Modifications:

- replace EventLoopValue with Result
- make whenComplete provide the Result

Result:

use the new shiny stuff
2019-01-05 08:08:47 +00:00
Johannes Weiss ce39ec20c0 all caps for SNI (#693)
Motivation:

In Swift, abbreviations use the same case for all letters, therefore it
should be `SNI` and not `Sni`.

Modifications:

changes `Sni` to `SNI`

Result:

more consistent with naming guidelines
2018-12-10 20:28:10 +00:00
Johannes Weiss cbc214938a first cut at B2MD v2 (#675)
Motivation:

Explain here the context, and why you're making that change.
What is the problem you're trying to solve.

Modifications:

Describe the modifications you've done.

Result:

After your change, what will change.
2018-12-10 16:23:12 +00:00
Johannes Weiss 9b78557aff kick off NIO2 (#678)
Motivation:

NIO2 development starts now.

Modifications:

Made NIO Swift 5-only for everything else see docs/public-api-changes-NIO1-to-NIO2.md

Result:

NIO2 development can start.
2018-12-07 21:15:34 +00:00
Johannes Weiss 08ab8b51cd remove ugly and unnecessary ignore result (_ = ...) (#652)
Motivation:

_ = expression() is ugly and in many cases unimportant. In fact we train
ourselves to overread it which makes special cases where you'd actually
expect a result to be used just look normal.

Modifications:

remove _ = from a lot of places. In many cases we already had a better
(and sometimes cheaper way) to not return a value but in some cases
(mostly `remove` functions) I added `@discardableResult`

Result:

NIO source code looks nicer
2018-11-13 14:49:08 +00:00
Johannes Weiss 2e96e47016 explain some force tries/unwraps (#619)
Motivation:

It's generally good style to explain why something needs to be force
unwrapped/tried if not obvious.

Modifications:

Add explanations to a bunch of places.

Result:

Code easier to understand.
2018-09-19 15:51:03 +01:00
Johannes Weiss f8600df5dc safer UnsafeRawBufferPointer use (#559)
Motivation:

Unsafe(Mutable)RawBufferPointers have a few APIs that make our code
easier to reason about. In this PR I'm trying to introduce some of it.

Modifications:

Improved UnsafeRawBufferPointer usage

Result:

code easier to reason about which hopefully leads to fewer bugs. Also:
In many cases we now get free bounds checking in debug mode, yay :).
2018-08-09 11:53:45 +01:00
Bas Broek a095decbc2 Prefer if case over switch
Motivation:

There are quite a few `switch`es that cover just two cases. Explicitly state this via an `if case` + `else` structure.

Modifications:

Changes something like:

switch a {
case .b:
  return c
default:
  return d
}

to

if case .b = a {
  return c
} else {
  return d
}

Result:

This should prevent misinterpretation and thus potential bugs in the future.
2018-03-19 14:45:32 +01:00
Bas Broek b180113d81 Improve switch readability
Motivation:
This changes two things:
- it removes the negation of non-used associated types (the removal of `(_)`).
- it prefers exhausting `switch`es over `default`ing.

This change does not impact bahavior; it is pure refactoring.

Modifications:

Omitting needless `(_)`'s and explicitly exhausting switches.

Result:

This change is pure refactoring.
2018-03-19 14:43:38 +01:00
Norman Maurer 273932ae36 Change ByteToMessageDecoder.decode and decodeLast to return an enum.
Motivation:

We used a bool to signal if we should continue decoding or not. Using an enum is more self-documenting.

Modifications:

Add DecodingState and use.

Result:

Code is more self-documenting.
2018-02-20 13:07:31 +01:00
Johannes Weiss 94213c74fd remove one Foundation import & one copy/roundtrip through Data
Motivation:

The SNI handler used Foundation for something that can be done fairly
easily without. Also avoids going through Data.

Modifications:

Removed Foundation method and implemented directly on Swift stdlib's
String encoding methods.

Result:

one less Foundation import
2018-02-19 12:59:03 +00:00
Johannes Weiss 4a09182a39 rewrite closures that just ignore their parameter & change whenComplete
to not return a value

Motivation:

We recently had a bug where we had `EventLoopFuture<EventLoopFuture<()>>` which didn't make any sense. The compiler couldn't catch that problem because we just ignored a closure's argument like this:

    future.then { _ in
        ...
    }

which is dangerous. For closures that take an empty tuple, the `_ in`
isn't actually required and the others should state the type they want
to ignore.

And most whenComplete calls can be better (and often shorter) expressed
by other combinators.

Modifications:

remove pretty much all closures which just blanket ignore their
parameter.

Result:

- no closures which just ignore their parameter without at least stating
  its type.
- rewrote all whenCompletes that actually used the value
2018-02-16 17:28:43 +00:00
Johannes Weiss eaa8ffaee4 remove redundant labels
Motivation:

Lots of our most important operations had redundant labels like

    func write(data: NIOAny)

the `data: ` label doesn't add anything meaningful and therefore it
should be removed.

Modifications:

removed lots of redundant labels

Result:

less redundant labels
2018-02-13 11:13:30 +00:00
Johannes Weiss eab7d314f3 make Channel non optional in ChannelHandlerContext 2018-01-30 12:03:51 +00:00
Johannes Weiss af4dabb0fa rename the Future's functor map function to map 2018-01-30 08:25:20 +00:00
Cory Benfield 9908b391db Prevent SniHandler wrongly calculating packet length. 2018-01-19 16:39:46 +00:00
Johannes Weiss db28cf4452 don't pretend user events are typed & remove tryUnwrap for in/outbound data 2018-01-19 14:12:57 +00:00
Norman Maurer 76482816e6 Prefix all ByteBuffer methods with get if these allow access to unitialized memory. 2017-12-15 12:24:09 +01:00
Cory Benfield 3da9f09d0a Add doc comments for NIOTLS 2017-11-30 12:39:06 +00:00
Johannes Weiß 33fe401322 rename Future/Promise to EventLoopFuture/EventLoopPromise 2017-11-21 17:41:36 +00:00
Cory Benfield 8efedf33fa Add ALPN handler 2017-11-01 16:14:11 +00:00
Johannes Weiß 20800ed454 use the now fully featured FixedWidthInteger instead of EndiannessInteger 2017-11-08 13:08:02 -08:00
Cory Benfield 8f2d17bc55 Break out common TLS events 2017-11-01 10:56:15 +00:00
Cory Benfield 8b860d3009 Add SNI handler 2017-10-30 10:58:26 +00:00