Repository: apple/swift-nio
File: Sources/NIOCore/AsyncChannel/AsyncChannel.swift (Swift)

Code before:
    ) throws -> NIOAsyncChannel<Inbound, Outbound> where Outbound == Never {
        channel.eventLoop.preconditionInEventLoop()
        let (inboundStream, outboundWriter):
            (NIOAsyncChannelInboundStream<Inbound>, NIOAsyncChannelOutboundWriter<Outbound>) =
                try channel._syncAddAsyncHandlersWithTransformations(
                    backPressureStrategy: backPressureStrategy,
                    isOutboundHalfClosureEnabled: isOutboundHalfClosureEnabled,
                    closeOnDeinit: false,
                    channelReadTransformation: channelReadTransformation
                )

        outboundWriter.finish()

        return .init(
            channel: channel,
            inboundStream: inboundStream,
            outboundWriter: outboundWriter
        )
    }

    /// Provides scoped access to the inbound and outbound side of the underlying ``Channel``.
    ///
    /// - Important: After this method returned the underlying ``Channel`` will be closed.
    ///
    /// - Parameter:
    ///     - isolatedTo: actor where this function should be isolated to
    ///     - body: A closure that gets scoped access to the inbound and outbound.
    public func executeThenClose<Result>(
        isolatedTo actor: isolated(any Actor)? = #isolation,
        _ body: (_ inbound: NIOAsyncChannelInboundStream<Inbound>, _ outbound: NIOAsyncChannelOutboundWriter<Outbound>)
            async throws -> Result
    ) async throws -> Result {
        let result: Result
        do {
            result = try await body(self._inbound, self._outbound)
        } catch let bodyError {
            do {
                self._outbound.finish()
                try await self.channel.close().get()
                throw bodyError
            } catch {
                throw bodyError
            }
        }

        self._outbound.finish()
        // We ignore errors from close, since all we care about is that the channel has been closed
        // at this point.
        self.channel.close(promise: nil)
        // `closeFuture` should never be failed, so we could ignore the error. However, do an
        // assertionFailure to guide bad Channel implementations that are incorrectly failing this

Review comment (suggestion):
Nit: the parameter name here is `actor` - `isolatedTo` is the label (you can think of it as a part of the method's name).

Code after:
    ) throws -> NIOAsyncChannel<Inbound, Outbound> where Outbound == Never {
        channel.eventLoop.preconditionInEventLoop()
        let (inboundStream, outboundWriter):
            (NIOAsyncChannelInboundStream<Inbound>, NIOAsyncChannelOutboundWriter<Outbound>) =
                try channel._syncAddAsyncHandlersWithTransformations(
                    backPressureStrategy: backPressureStrategy,
                    isOutboundHalfClosureEnabled: isOutboundHalfClosureEnabled,
                    closeOnDeinit: false,
                    channelReadTransformation: channelReadTransformation
                )

        outboundWriter.finish()

        return .init(
            channel: channel,
            inboundStream: inboundStream,
            outboundWriter: outboundWriter
        )
    }

    /// Provides scoped access to the inbound and outbound side of the underlying ``Channel``.
    ///
    /// - Important: After this method returned the underlying ``Channel`` will be closed.
    ///
    /// - Parameter body: A closure that gets scoped access to the inbound and outbound.
    @_disfavoredOverload
    public func executeThenClose<Result>(
        _ body: (_ inbound: NIOAsyncChannelInboundStream<Inbound>, _ outbound: NIOAsyncChannelOutboundWriter<Outbound>)
            async throws -> Result
    ) async throws -> Result {
        let result: Result
        do {
            result = try await body(self._inbound, self._outbound)
        } catch let bodyError {
            do {
                self._outbound.finish()
                try await self.channel.close().get()
                throw bodyError
            } catch {
                throw bodyError
            }
        }

        self._outbound.finish()
        // We ignore errors from close, since all we care about is that the channel has been closed
        // at this point.
        self.channel.close(promise: nil)
        // `closeFuture` should never be failed, so we could ignore the error. However, do an
        // assertionFailure to guide bad Channel implementations that are incorrectly failing this
        // future to stop failing it.
        do {