Commit Graph

5 Commits

Author SHA1 Message Date
Franz Busch e7e83d6aa4
Land `NIOAsyncChannel` as SPI (#2397)
* Land `NIOAsyncChannel` as SPI

# Motivation

We want to provide bridges from NIO `Channel`s to Swift Concurrency. In previous PRs, we already landed the building blocks namely `NIOAsyncSequenceProducer` and `NIOAsyncWriter`. These two types are highly performant bridges between synchronous and asynchronous code that respect back-pressure.
The next step is to build convenience methods that wrap a `Channel` with these two types.

# Modification
This PR adds a new type called `NIOAsyncChannel` that is capable of wrapping a `Channel`. This is done by adding two handlers to the channel pipeline that are bridging to the `NIOAsyncSequenceProducer` and `NIOAsyncWriter`.
The new `NIOAsyncChannel` type exposes three properties. The underlying `Channel`, a `NIOAsyncChannelInboundStream` and a `NIOAsyncChannelOutboundWriter`. Using these three types the user a able to read/write into the channel using `async` methods.

Importantly, we are landing all of this behind the `@_spi(AsyncChannel`. This allows us to merge PRs while we are still working on the remaining parts such as protocol negotiation.

# Result
We have the first part necessary for our async bridges. Follow up PRs will include the following things:
1.  Bootstrap support
2. Protocol negotiation support
3. Example with documentation

* Add AsyncSequence bridge to NIOAsyncChannelOutboundWriter

* Code review

* Prefix temporary spi public method

* Rename writeAndFlush to write
2023-04-06 05:26:32 -07:00
carolinacass af41276062
Use #fileID/#filePath instead of #file (#2306)
Motivation:

#fileID introduced in Swift 5.3, so no longer need to use #file anywhere

Modifications:

Changed #file to #filePath or #fileID depending on the situation
2022-11-03 16:43:13 +00: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
Franz Busch f144292e5d
Implement a `NIOAsyncWriter` (#2251)
* Implement a `NIOAsyncWriter`

# Motivation
We previously added the `NIOAsyncProducer` to bridge between the NIO channel pipeline and the asynchronous world. However, we still need something to bridge writes from the asynchronous world back to the NIO channel pipeline.

# Modification
This PR adds a new `NIOAsyncWriter` type that allows us to asynchronously `yield` elements to it. On the other side, we can register a `NIOAsyncWriterDelegate` which will get informed about any written elements. Furthermore, the synchronous side can toggle the writability of the `AsyncWriter` which allows it to implement flow control.
A main goal of this type is to be as performant as possible. To achieve this I did the following things:
- Make everything generic and inlinable
- Use a class with a lock instead of an actor
- Provide methods to yield a sequence of things which allows users to reduce the amount of times the lock gets acquired.

# Result
We now have the means to bridge writes from the asynchronous world to the synchronous

* Remove the completion struct and incorporate code review comments

* Fixup some refactoring leftovers

* More code review comments

* Move to holding the lock around the delegate and moved the delegate into the state machine

* Comment fixups

* More doc fixes

* Call finish when the sink deinits

* Refactor the writer to only yield Deques and rename the delegate to NIOAsyncWriterSinkDelegate

* Review

* Fix some warnings

* Fix benchmark sendability

* Remove Failure generic parameter and allow sending of an error through the Sink
2022-09-21 02:53:53 -07:00
David Nadoba 4f2c6a3e0b
Add `collect(upTo:) -> ByteBuffer` and variations to `AsyncSequence` (#2038) 2022-02-03 10:31:09 -08:00