Skip to content

Commit 2140160

Browse files
authored
Remove dependency on SPI (#419)
Motivation: Remove dependency on SPI so that we can cut a release without introducing dependency on code subject to change. Modifications: Remove all code which introduces a dependency on the NIOAsyncChannel SPI Result: Code inside SPI is removed
1 parent 8275314 commit 2140160

File tree

5 files changed

+3
-830
lines changed

5 files changed

+3
-830
lines changed

Sources/NIOHTTP2/HTTP2ChannelHandler+InlineStreamMultiplexer.swift

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
//
1313
//===----------------------------------------------------------------------===//
1414

15-
@_spi(AsyncChannel) import NIOCore
15+
import NIOCore
1616

1717
internal struct InlineStreamMultiplexer {
1818
private let context: ChannelHandlerContext
@@ -211,36 +211,3 @@ extension InlineStreamMultiplexer {
211211
self.commonStreamMultiplexer.setChannelContinuation(streamChannels)
212212
}
213213
}
214-
215-
extension NIOHTTP2Handler {
216-
/// A variant of `NIOHTTP2Handler.StreamMultiplexer` which creates a child channel for each HTTP/2 stream and
217-
/// provides access to inbound HTTP/2 streams.
218-
///
219-
/// In general in NIO applications it is helpful to consider each HTTP/2 stream as an
220-
/// independent stream of HTTP/2 frames. This multiplexer achieves this by creating a
221-
/// number of in-memory `HTTP2StreamChannel` objects, one for each stream. These operate
222-
/// on ``HTTP2Frame/FramePayload`` objects as their base communication
223-
/// atom, as opposed to the regular NIO `SelectableChannel` objects which use `ByteBuffer`
224-
/// and `IOData`.
225-
///
226-
/// Outbound stream channel objects are initialized upon creation using the supplied `streamStateInitializer` which returns a type
227-
/// `Output`. This type may be `HTTP2Frame` or changed to any other type.
228-
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
229-
@_spi(AsyncChannel)
230-
public struct AsyncStreamMultiplexer<InboundStreamOutput> {
231-
private let inlineStreamMultiplexer: InlineStreamMultiplexer
232-
public let inbound: NIOHTTP2InboundStreamChannels<InboundStreamOutput>
233-
234-
// Cannot be created by users.
235-
internal init(_ inlineStreamMultiplexer: InlineStreamMultiplexer, continuation: any AnyContinuation, inboundStreamChannels: NIOHTTP2InboundStreamChannels<InboundStreamOutput>) {
236-
self.inlineStreamMultiplexer = inlineStreamMultiplexer
237-
self.inlineStreamMultiplexer.setChannelContinuation(continuation)
238-
self.inbound = inboundStreamChannels
239-
}
240-
241-
/// Create a stream channel initialized with the provided closure
242-
public func createStreamChannel<Output: Sendable>(_ initializer: @escaping NIOChannelInitializerWithOutput<Output>) async throws -> Output {
243-
return try await self.inlineStreamMultiplexer.createStreamChannel(initializer).get()
244-
}
245-
}
246-
}

Sources/NIOHTTP2/HTTP2ChannelHandler.swift

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1140,16 +1140,4 @@ extension NIOHTTP2Handler {
11401140
throw NIOHTTP2Errors.missingMultiplexer()
11411141
}
11421142
}
1143-
1144-
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
1145-
internal func syncAsyncStreamMultiplexer<Output: Sendable>(continuation: any AnyContinuation, inboundStreamChannels: NIOHTTP2InboundStreamChannels<Output>) throws -> AsyncStreamMultiplexer<Output> {
1146-
self.eventLoop!.preconditionInEventLoop()
1147-
1148-
switch self.inboundStreamMultiplexer {
1149-
case let .some(.inline(multiplexer)):
1150-
return AsyncStreamMultiplexer(multiplexer, continuation: continuation, inboundStreamChannels: inboundStreamChannels)
1151-
case .some(.legacy), .none:
1152-
throw NIOHTTP2Errors.missingMultiplexer()
1153-
}
1154-
}
11551143
}

Sources/NIOHTTP2/HTTP2CommonInboundStreamMultiplexer.swift

Lines changed: 0 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -451,124 +451,3 @@ internal protocol AnyContinuation {
451451
func finish()
452452
func finish(throwing error: Error)
453453
}
454-
455-
456-
/// `NIOHTTP2InboundStreamChannels` provides access to inbound stream channels as a generic `AsyncSequence`.
457-
/// They make use of generics to allow for wrapping the stream `Channel`s, for example as `NIOAsyncChannel`s or protocol negotiation objects.
458-
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
459-
@_spi(AsyncChannel)
460-
public struct NIOHTTP2InboundStreamChannels<Output>: AsyncSequence {
461-
public struct AsyncIterator: AsyncIteratorProtocol {
462-
public typealias Element = Output
463-
464-
private var iterator: AsyncThrowingStream<Output, Error>.AsyncIterator
465-
466-
init(_ iterator: AsyncThrowingStream<Output, Error>.AsyncIterator) {
467-
self.iterator = iterator
468-
}
469-
470-
public mutating func next() async throws -> Output? {
471-
try await self.iterator.next()
472-
}
473-
}
474-
475-
public typealias Element = Output
476-
477-
private let asyncThrowingStream: AsyncThrowingStream<Output, Error>
478-
479-
private init(_ asyncThrowingStream: AsyncThrowingStream<Output, Error>) {
480-
self.asyncThrowingStream = asyncThrowingStream
481-
}
482-
483-
public func makeAsyncIterator() -> AsyncIterator {
484-
AsyncIterator(self.asyncThrowingStream.makeAsyncIterator())
485-
}
486-
}
487-
488-
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
489-
extension NIOHTTP2InboundStreamChannels {
490-
/// `Continuation` is a wrapper for a generic `AsyncThrowingStream` to which inbound HTTP2 stream channels are yielded..
491-
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
492-
struct Continuation: AnyContinuation {
493-
private var continuation: AsyncThrowingStream<Output, Error>.Continuation
494-
495-
internal init(
496-
continuation: AsyncThrowingStream<Output, Error>.Continuation
497-
) {
498-
self.continuation = continuation
499-
}
500-
501-
/// `yield` takes a channel as outputted by the stream initializer and yields the wrapped `AsyncThrowingStream`.
502-
///
503-
/// It takes channels as as `Any` type to allow wrapping by the stream initializer.
504-
func yield(any: Any) {
505-
let yieldResult = self.continuation.yield(any as! Output)
506-
switch yieldResult {
507-
case .enqueued:
508-
break // success, nothing to do
509-
case .dropped:
510-
preconditionFailure("Attempted to yield when AsyncThrowingStream is over capacity. This shouldn't be possible for an unbounded stream.")
511-
case .terminated:
512-
preconditionFailure("Attempted to yield to AsyncThrowingStream in terminated state.")
513-
default:
514-
preconditionFailure("Attempt to yield to AsyncThrowingStream failed for unhandled reason.")
515-
}
516-
}
517-
518-
/// `finish` marks the continuation as finished.
519-
func finish() {
520-
self.continuation.finish()
521-
}
522-
523-
/// `finish` marks the continuation as finished with the supplied error.
524-
func finish(throwing error: Error) {
525-
self.continuation.finish(throwing: error)
526-
}
527-
}
528-
529-
530-
/// `initialize` creates a new `Continuation` object and returns it along with its backing `AsyncThrowingStream`.
531-
/// The `StreamChannelContinuation` provides access to the inbound HTTP2 stream channels.
532-
///
533-
/// - Parameters:
534-
/// - inboundStreamInititializer: A closure which initializes the newly-created inbound stream channel and returns a generic.
535-
/// The returned type corresponds to the output of the channel once the operations in the initializer have been performed.
536-
/// For example an `inboundStreamInititializer` which inserts handlers before wrapping the channel in a `NIOAsyncChannel` would
537-
/// have a `Output` corresponding to that `NIOAsyncChannel` type. Another example is in cases where there is
538-
/// per-stream protocol negotiation where `Output` would be some form of `NIOProtocolNegotiationResult`.
539-
static func initialize(inboundStreamInitializerOutput: Output.Type = Output.self) -> (NIOHTTP2InboundStreamChannels<Output>, Continuation) {
540-
let (stream, continuation) = AsyncThrowingStream.makeStream(of: Output.self)
541-
return (.init(stream), Continuation(continuation: continuation))
542-
}
543-
}
544-
545-
#if swift(>=5.7)
546-
// This doesn't compile on 5.6 but the omission of Sendable is sufficient in any case
547-
@available(*, unavailable)
548-
extension NIOHTTP2InboundStreamChannels.AsyncIterator: Sendable {}
549-
550-
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
551-
extension NIOHTTP2InboundStreamChannels: Sendable where Output: Sendable {}
552-
#else
553-
// This wasn't marked as sendable in 5.6 however it should be fine
554-
// https://forums.swift.org/t/so-is-asyncstream-sendable-or-not/53148/2
555-
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
556-
extension NIOHTTP2InboundStreamChannels: @unchecked Sendable where Output: Sendable {}
557-
#endif
558-
559-
560-
#if swift(<5.9)
561-
// this should be available in the std lib from 5.9 onwards
562-
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
563-
extension AsyncThrowingStream {
564-
public static func makeStream(
565-
of elementType: Element.Type = Element.self,
566-
throwing failureType: Failure.Type = Failure.self,
567-
bufferingPolicy limit: Continuation.BufferingPolicy = .unbounded
568-
) -> (stream: AsyncThrowingStream<Element, Failure>, continuation: AsyncThrowingStream<Element, Failure>.Continuation) where Failure == Error {
569-
var continuation: AsyncThrowingStream<Element, Failure>.Continuation!
570-
let stream = AsyncThrowingStream<Element, Failure>(bufferingPolicy: limit) { continuation = $0 }
571-
return (stream: stream, continuation: continuation!)
572-
}
573-
}
574-
#endif

0 commit comments

Comments
 (0)