Commit Graph

81 Commits

Author SHA1 Message Date
aryan-25 a1605a3303 Use explicit class name in all Self.[un]wrap{In}{Out}bound{In}{Out} calls (#3463)
### Motivation:

Swift does not currently generic specialize static methods on final
classes that have no parent classes when the method is implemented in a
protocol. This means that calling such methods through `Self` will not
involve a generic specialization, whereas using the explicit type name
will.

This pattern manifests in the `[un]wrap{In}{Out}bound{In}{Out}` static
methods defined in the
[`ChannelInboundHandler`](https://github.com/apple/swift-nio/blob/27146d484478b1bb0f150e848758f3a34ed9cbd0/Sources/NIOCore/TypeAssistedChannelHandler.swift#L60)
and
[`ChannelOutboundHandler`](https://github.com/apple/swift-nio/blob/27146d484478b1bb0f150e848758f3a34ed9cbd0/Sources/NIOCore/TypeAssistedChannelHandler.swift#L95)
protocols and their use from all channel handler classes. As such, we
should replace the `Self` part in all
`Self.[un]wrap{In}{Out}bound{In}{Out}` calls with the explicit class
name.

### Modifications:

Replaced all `Self.[un]wrap{In}{Out}bound{In}{Out}` calls to use the
explicit class name.

### Result:

Eliminates unnecessary overhead.
2025-12-15 17:36:11 +00:00
Johannes Weiss 0b65385fad improve inEventLoop checks (#3302)
### Motivation:

`inEventLoop` is very much in the performance path of SwiftNIO,
especially these days with Concurrency, `NIOLoopBound` and friends.
Previously, we relied on `pthread_equal(pthread_self(), myPthread)`,
however, this could cause a number of issues.

1. Holding onto a `pthread_t` after `.join` is actually illegal (fixed
in #3297)
2. Potential ABA issues when `pthread_t` pointer are re-used for new
pthreads
3. Fix would require a lock around `myPthread` which makes things (2x
slower, even without contention)

### Modifications:

- New type `SelectableEventLoopUniqueID` which can be packed into a
`UInt`
- Attach them into a C thread local

### Result:

- Even faster than the old, incorrect version
- old: `measuring: el_in_eventloop_100M: 0.257395375, 0.241049208,
0.243188792, 0.259125916, 0.24843225, 0.229690125, 0.244281541,
0.225078834, 0.236395, 0.233305167`
- new: `measuring: el_in_eventloop_100M: 0.175561125, 0.187225625,
0.199269375, 0.19740975, 0.1922695, 0.179850958, 0.177612458,
0.17665125, 0.17897475, 0.18038775`
- More correct
- Groundwork to make #3297 not make things slower
2025-07-14 17:15:10 +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
Cory Benfield abe4f1bcb6 Replace almost all public static lets with computed vars (#3229)
Motivation:

Public static lets can serve a bunch of roles, but one of them is to
store simple constants: integers, and other trivial types, for example.
This is a nice pattern and for internal and private static lets it works
well, but for public ones it produces some inefficient code.

In particular, it has two downsides. First, it allocates storage for
that value. We don't actually need to allocate a few hundred extra
megabytes for the various integers we want to store.

Secondly, it forces calling code to access the address and call the
dispatch_once code in order to get hold of the value. For trivial types
we don't need that cost: they can just know what the value is directly.

Inlinable computed vars avoid all of these costs: they have no size
overhead for storage, and they are visible to all clients so their
values can be directly assembled.

While I'm here, I added a bunch of other inlinable annotations for a few
trivial data types I stumbled onto.

Modifications:

- Added loads of inlinables. Like, loads.
- Swapped many static lets to static vars.

Result:

Better codegen, smaller memory footprints, more attributes.
2025-05-02 16:08:10 +01:00
George Barnett b34052b28b Swift concurrency for NIOWebSocketTests (#3208) 2025-04-15 16:38:21 +01:00
Raghav Roy 8440498328 Add More Peek API Variants for ByteBuffer (#3174)
### Motivation:

Existing get APIs require passing an explicit index and can be misused,
leading to verbose and error-prone code. Adding peek variants that
automatically use the current readerIndex improves safety and clarity.
This aims to address issue #2034 and issue #2736, and is a continuation
of PR #3157

### Modifications:

Introduced peekSlice(), peekLengthPrefixedSlice(), peekData(),
peekUUIDBytes() and peekWebSocketErrorCode().
Added tests for each peek API covering normal, empty and repeated peek
scenarios.

### Result:

Developers can now use nonmutating peek APIs to inspect ByteBuffer
contents without altering the reader index.
2025-04-10 14:44:53 +00:00
Rick Newton-Rogers 5fe3d44328 Enable strict concurrency checking for NIOWebSocket (#3127)
Enable strict concurrency checking for NIOWebSocket

### Motivation:

To ensure NIOWebSocket concurrency safety.

### Modifications:

* Enable strict concurrency checking in the package manifest.
* `NIOWebSocketClientUpgrader._upgrade` private function generic return
type is marked as `Sendable` in line with the only method which calls
it.
* `NIOWebSocketServerUpgrader._upgrade` private function generic return
type is marked as `Sendable` in line with the only method which calls
it.
* `WebSocketOpcode.allCases` public computed variable is replaced with a
`let` which manually enumerates the cases instead

### Result:

`NIOWebSocket` does not warn of concurrency issues, builds will warn and
CI will fail if regressions are introduced.
2025-03-07 09:34:06 +00:00
John Zhou 2620f8e9a0 Fix WebSocketProtocolErrorHandler sending the close frame with appropriate masking key (#3040)
Enhance `WebSocketProtocolErrorHandler` to correctly add masking key for
client/server.

### Motivation:
In `NIOWebSocket`, the automatic error handling provided by
`WebSocketProtocolErrorHandler` offers a convenient way for both clients
and servers to handle protocol-level errors. However, the
`WebSocketFrame` used in `WebSocketProtocolErrorHandler` does not fully
adhere to the RFC 6455 standard. Specifically, as per [RFC 6455 Section
5.1](https://datatracker.ietf.org/doc/html/rfc6455#section-5.1), a
client *must* mask all frames it sends to the server, while a server
*must not* mask any frames it sends to the client. This PR addressed
this discrepancy to ensure compliance with the WebSocket protocol.

### Modifications:
In the `WebSocketProtocolErrorHandler` initializer, the user can specify
whether the handler is used for a WebSocket client or server. Within the
`errorCaught` method, the `WebSocketFrame` will include a maskingKey if
the handler is used by a client, or nil if it is used by a server.

Additionally, the `@unchecked` annotation is removed from
`NIOWebSocketServerUpgrader` since the project is now using swift 5.9
toolchain.

### Result:
The `WebSocketProtocolErrorHandler` is more robust and can correctly
close the connection is error occurs.
2025-01-16 11:08:33 +00:00
George Barnett 8bf4034462 Deprecate not-actually-public Base64 APIs (#3022)
Motivation:

The not-actually-public `_NIOBase64` module has public extensions on
`String`. These are visible when transitively depending on `_NIOBase64`
but shouldn't be.

Modifications:

- Add underscored variants
- Deprecate public variants

Result:

Stricter API
2024-12-12 10:29:03 +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
Adam Fowler d8363850ce Add WebSocketFrame.reservedBits OptionSet (#2971)
Add support for treating WebSocketFrame reserved bits as an option set

### Motivation:

I would like to do mask operations on the reserved bits of the
WebSocketFrame eg check none are set, check only bits in a mask are set.
With the current public interface it is only possible to check the state
of one bit at a time.

### Modifications:

Add `WebSocketFrame.ReservedBits` OptionSet
Add computed member `WebSocketFrame.reservedBits`  

### Result:

I can now check the status of multiple bits in one operation eg
`frame.reservedBits.isEmpty`
`frame.reservedBits.itersection([.rsv1, .rsv2]).isEmpty`
2024-11-15 17:45:38 +00:00
Rick Newton-Rogers adfd61adc5 Use Swift 6.0 docs pipeline (#2966)
### Motivation:

Documentation checking catches more issues in Swift 6.0.

### Modifications:

Adopt the Swift 6.0 image and fix the errors.

### Result:

More accurate docs.
2024-11-07 13:03:47 +00:00
Mirza Učanbarlić 74f7b1e675 Adding a nicer description for WebSocketFrame. (#2862)
### Motivation:

Resolving the following issue:
https://github.com/apple/swift-nio/issues/2828

### Modifications:

Making `WebSocketFrame` conform to `CustomStringConvertible`.

### Result:

A nicer description for `WebSocketFrame`.

---------

Co-authored-by: Franz Busch <f.busch@apple.com>
2024-09-04 11:06:54 +00:00
Valeriy Van d62a876741 Fix typo in comment in WebSocketErrorCodes.swift (#2604) 2024-08-05 09:18:15 +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
Johannes Weiss 7948ed2104 ChannelHandler: provide static (un)wrap(In|Out)bound(In|Out) (#2791) 2024-07-18 11:55:48 +01:00
Harish Yerra a0e0c68d71 [arch] Add arm64_32 to the 32-bit platform check (#2625)
On watchOS, the arm64_32 bit architecture restricts software to ILP32 which means integers are 32-bit. This expands our existing 32-bit checks to include arm64_32.
2024-01-17 05:34:01 -08:00
Franz Busch 702cd7c56d Fix the typed HTTP upgrade compiler guards (#2594)
The compiler guards were unnecessarily complex and I also didn't cover 3 methods where we used the types.
2023-11-16 03:30:21 -08:00
Franz Busch c46199386c Revert "Back out new typed HTTP protocol upgrader (#2579)" (#2593)
* Revert "Back out new typed HTTP protocol upgrader (#2579)"

# Motivation
We have reverted the typed HTTP protocol upgrader pieces since adopters were running into a compiler bug (https://github.com/apple/swift/pull/69459) that caused the compiler to emit strong references to `swift_getExtendedExistentialTypeMetadata`. The problem is that `swift_getExtendedExistentialTypeMetadata` is not available on older runtimes before constrained existentials have been introduced. This caused adopters to run into runtime crashes when loading any library compiled with this NIO code.

# Modifications
This PR reverts the revert and guard all new code in a compiler guard that checks that we are either on non-Darwin platforms or on a new enough Swift compiler that contains the fix.

# Result
We can offer the typed HTTP upgrade code to our adopters again.

* Add compiler guards
2023-11-15 18:58:27 +00:00
Franz Busch 8c238f2cc1 Back out new typed HTTP protocol upgrader (#2579)
# Motivation
We got reports in https://github.com/apple/swift-nio/issues/2574 that our new typed HTTP upgrader are hitting a Swift compiler bug which manifests in a runtime crash on older iOS/macOS/etc.

# Modification
This PR backs out the new typed HTTP protocol upgrader APIs so that we can unblock our users until the Swift compiler bug is fixed.

# Result
No more crashes for our users.
2023-10-27 15:48:23 +01: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 4ab8b98f9d Introduce new typed HTTPClientUpgrader and WebSocketClientUpgrader (#2526)
* Introduce new typed `HTTPClientUpgrader` and `WebSocketClientUpgrader`

# Motivation
In my previous PR https://github.com/apple/swift-nio/pull/2517, I added a new typed `HTTPServerUpgrader` and corresponding implementation for the `WebSocketServerUpgrader`. The goal of those is to carry type information across HTTP upgrades which allows us to build fully typed pipelines.

# Modification
This PR adds a few things:
1. A new `NIOTypedHttpClientUpgradeHandler` + `NIOTypedHttpClientProtocolUpgrader`. I also moved the state handling to a separate state machine. Similar to the server PR I did not unify the state machine between the newly typed and untyped upgrade handlers since they differ in logic.
2. A new `NIOTypedWebSocketClientUpgrader`
3. An overhauled WebSocket client example.

# Result
This is the last missing piece of dynamic pipeline changing where we did not carry around the type information. After this PR lands, we can finalize the `AsyncChannel` and async typed NIO pieces.

* Remove availability on the protocols
2023-10-06 16:33:25 +01:00
Franz Busch de07e573d6 Introduce new typed HTTPServerUpgrader and WebSocketServerUpgrader (#2517)
* Introduce new typed `HTTPServerUpgrader` and `WebSocketServerUpgrader`

# Motivation
With our new `NIOAsyncChannel` and typed bootstrap APIs we want to be able to let users spell out their pipeline in a typed way. Pipelines can contain handlers that have to make a forking decision such as HTTP upgrading. Our current `HTTPServerUpgradeHandler` is one of those handlers but it lacks strict typing. To interact nicely with our new typed APIs we need to have a new variant of the `HTTPServerUpgradeHandler` that can carry type information.

# Modification
This PR adds a few things:
1. A new `NIOTypedHTTPServerUpgradeHandler` + `NIOTypedHTTPServeProtocolUpgrader`. I also moved the state handling logic to a separate state machine. I thought about unifying the state machines of the _old_ handler and the new one but they differ in behaviour which makes the state machine more complicated.
2. A new `NIOTypedWebSocketServerUpgrader` that conforms to `NIOTypedHTTPServerProtocolUpgrader`
3. An overhauled WebSocket server example that fully uses Concurrency.

# Result
We now have a way to fully type the server side of HTTP protocol upgrading.

Code review

Update parameter names for new API and fix example

* Introduce new configuration struct and rename to `UpgradablePipeline`

* Review comments
2023-10-02 07:26:16 -07:00
Rick Newton-Rogers 67553a7d6d Bump minimum Swift version to 5.7 (#2524)
* Bump minimum Swift version to 5.7

Motivation:

Now that Swift 5.9 is GM we should update the supported versions and
remove 5.6

Modifications:

* Update `Package.swift`
* Remove `#if swift(>=5.7)` guards
* Delete the 5.6 docker compose file and make a 5.10 one
* Update integration test script
* Update docs

Result:

Remove support for Swift 5.6, add 5.10

* fix indentation issues

* 5.9 docker image use release image
2023-10-02 11:38:07 +01:00
Natik Gadzhi 34a7663c05 Make ByteBuffer Codable (#2509)
This commit adds Codable to ByteBuffer. It encodes in Base64 into a singleValue
container.

- Base64 implementation moved into _NIODataStructures
- Base64 now supports decoding.
2023-08-30 10:32:45 +01:00
Franz Busch e865f6163f Use #if canImport(Darwin) where possible (#2446) 2023-06-22 10:12:01 +01: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
David Nadoba 06d4028cde Add missing Sendable requirements (#2305) 2022-11-03 14:41:42 +01:00
George Barnett d086bab75a Make NIOWebSocketServerUpgrader Sendable (#2304)
Motivation:

The `NIOWebSocketServerUpgrader` is marked as not being `Sendable`, but
it has no mutable state and makes no assumptions about the event loop it
is invoked on, so it should be `Sendable`. The two user-provided
callbacks which are injected in `init` are marked as being `Sendable`
but require Swift 5.7 to express this safely.

Modifications:

- Add `@unchecked Sendable` conformance to `NIOWebSocketServerUpgrader`

Result:

- `NIOWebSocketServerUpgrader` is Sendable.
2022-10-28 08:46:41 -07:00
David Nadoba 16b5b2b793 Replace NIOSendable with Sendable (#2291) 2022-10-13 15:56:27 +01:00
David Nadoba c7b4989b02 Remove #if compiler(>=5.5) (#2292)
### Motivation
We only support Swift 5.5.2+.

### Modification
Remove all `#if swift(>=5.5)` conditional compilation blocks.

### Result
less branching
2022-10-13 07:17:46 -07:00
George Barnett fcca969463 Raise minimum supported Swift version from 5.4 to 5.5 (#2267)
Motivation:

SwiftNIO periodically drops support for older Swift versions. Now that
5.7 has been released, 5.4 will be dropped.

Modifications:

- Remove 5.4 specific Package.swift and docker-compose
- Update the 5.7 docker-compose to use the released 5.7 and move from
  focal (2004) to jammy (2204)
- Remove unused swiftformat from Dockerfile
- Update tools version in syscall wrapper tests to 5.5
- Update docs

Results:

Minimum Swift version is 5.5
2022-09-29 11:47:44 +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 f1d62128c4 Adopt Sendable for Closures in NIOWebSocket (#2218)
Co-authored-by: Cory Benfield <lukasa@apple.com>
2022-07-05 04:07:44 -07:00
David Nadoba fbe7ef484a Adopt Sendable for Types in NIOWebSocket (#2217) 2022-07-05 11:50:55 +01:00
BenedictSt d489d9f38f Fixed some typos (#2051)
Fixed some typos.
2022-02-22 01:37:47 -08:00
Johannes Weiss b2629903ca ByteBuffer: provide multi read/write int methods (#1987)
Motivation:

Many network protocols (especially for example NFS) have quite a number
of integer values next to each other. In NIO, you'd normally parse/write
them with multiple read/writeInteger calls.

Unfortunately, that's a bit wasteful because we're checking the bounds
as well as the CoW state every time.

Modifications:

- Provide read/writeMultipleIntegers for up to 15 FixedWidthIntegers.
- Benchmarks

Result:

Faster code. For 10 UInt32s, this is a 5x performance win on my machine,
see benchmarks.
2021-11-22 14:58:52 +00:00
Cory Benfield 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
Maxim Zaks c776f6e539 Improving performance of base64 encoding by about 10% (#1862)
* Improving performance of base64 encoding by about 10%

* revert alphabet change and use String(customUnsafeUninitializedCapacity:initializingUTF8With:)

* Add performance test for random request key generation

* use reduce

* fix indentation

* add `@inlinable` on custom unsefe inializer for older Swift version

* fix issues mentioned in review

Co-authored-by: Cory Benfield <lukasa@apple.com>
2021-06-07 11:12:06 +01:00
David Nadoba 465f87dd7c Random WebSocket Request Key (#1855)
* add randomRequestKey method

* fix some typos

* fix compilation on 5.0

* run generate_linux_tests.rb

* add test with default random number generator

* @inlineable

* base64Encoding @inlineable
2021-05-24 16:02:16 +01:00
David Nadoba 4ded06871a Add method to generate a random mask (#1824)
* add static method to generate a random mask

* use SystemRandomNumberGenerator by default and add documentation

* use WebSocketMaskingKey instead of Self to support Swift 5.0

* add tests for random masking key

* add return keyword to support Swift 5.0

* run scripts/generate_linux_tests.rb

* rename T to Generator

* test SystemRandomNumberGenerator

* Revert "test SystemRandomNumberGenerator"

This reverts commit d9bdbe57ac.

* work around thread sanitizer bug on Swift 5.3
2021-05-24 10:12:36 +01:00
David Nadoba 6befe13e23 WebSocket Frame Aggregator (#1823)
* implement and test WebSocketFrameAggregator

* add documentation

* fix review comments

* run scripts/generate_linux_tests.rb

* fix Swift 5.0

* move redundant channel creation into init

* create channel in setUp

* wrap all trys in XCTAssertNoThrow

* cache accumulatedFrameSize

* accumulate buffered frames into the first frames data buffer

* Revert "accumulate buffered frames into the first frames data buffer"

This reverts commit 0f83823f95.

* use channel allocator
2021-04-30 15:39:24 +01:00
Shekhar Rajak 2900f03352 ByteToMessageDecoder: Default implementation for decodeLast should be provided (#1426)
* removed decodeLast function from NIOChatServer

* updated decodeLast function from WebSocketFrameDecoder

* default implementation of decodeLast function

* removed implementation of decodeLast in WebSocketFrameDecoder
2020-03-04 16:22:06 +00:00
trungducc 8ad2549a49 Stop copying Strings into Arrays for SHA1 (#1413)
Motivation:

Resolve #1409

Modifications:

Using withContiguousStorageIfAvailable if string.utf8 supports an internal representation in a form. Otherwise, fall back to use withUnsafeBufferPointer.

Result:

Save an allocation for each hash function update
2020-02-25 08:52:36 +00:00
Liam Flynn 8ccae09377 Correct NIOHTTPWebClientSocketUpgrader to NIOHTTPWebSocketClientUpgrader (#1336)
Motivation:

The class name was a typo.
It is a client upgrader that upgrades WebSocket connections, so the updated name suits better.

Modifications:

Change class name of ‘NIOHTTPWebClientSocketUpgrader’ to ‘NIOHTTPWebSocketClientUpgrader’.
Update the WebSocket client example that uses this class.
Add a typealias to allow the old class name to be used.

Result:

Improved naming.
2020-01-15 09:24:50 +00:00
Fabian Fett 653492753c Faster Base64 Encoding for NIOWebsocket connections (#1328)
Motivation:

In performance tests was shown that the current base 64 encoding function doesn’t perform very well.

https://github.com/apple/swift-nio/issues/1322

Modifications:

This commit replaces the current Base64 implementation with a more performant one (by using UInt8 bytes instead of Unicode.Scalars).

Result:

The API will stay the same. Base64 encoding is just faster.
2019-12-24 12:41:43 +00:00
Cory Benfield b053967abd Support writing WS header to user buffer. (#1168)
Motivation:

In some cases it may be possible to write the (usually small) web socket
frame header to the buffer provided by the user. If we do this we can
avoid an extra pipeline traversal for the small write. This is only
going to be a performance win in cases where we can avoid a
copy-on-write operation on the buffer, but if we can then it's a useful
small win to achieve.

Modifications:

- Refactored the WebSocketFrameEncoder to potentially prepend the frame
    header.
- Added a missing @inlinable attribute.
- Tests.

Result:

Potentially improved performance.
2019-11-27 18:52:03 +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
Richard Low b1834d4459 Add withContiguousStorageIfAvailable implementation to WebSocketMaskingKey (#1237)
Motivation:

It's faster and contiguous storage is trivially available

Modifications:

- Implement WebSocketMaskingKey.withContiguousStorageIfAvailable
- Make it @inlinable, requiring promoting WebSocketMaskingKey.key to internal
  so renamed to _key.

Result:

Writing WebSocketMaskingKey into ByteBuffer is about 2x faster.
2019-11-12 17:59:04 +00:00