Repository: apple/swift-nio
File: Sources/NIOPosix/PendingWritesManager.swift (Swift)

Code before:

    /// Trigger a vector write operation. In other words: Write multiple contiguous arrays of bytes.
    ///
    /// - Parameters:
    ///   - operation: The vector write operation to use. Usually `writev`.
    private func triggerVectorBufferWrite(
        _ operation: (UnsafeBufferPointer<IOVector>) throws -> IOResult<Int>
    ) throws -> OneWriteOperationResult {
        assert(
            self.state.isFlushPending && !self.state.isEmpty && self.isOpen,
            "vector write called in illegal state: flush pending: \(self.state.isFlushPending), empty: \(self.state.isEmpty), isOpen: \(self.isOpen)"
        )
        let result = try doPendingWriteVectorOperation(
            pending: self.state,
            bufferPool: bufferPool,
            { try operation($0) }
        )
        return self.didWrite(itemCount: result.itemCount, result: result.writeResult)
    }

    /// Fail all the outstanding writes.
    func failAll(error: Error, close: Bool) {
        if close {
            assert(self.isOpen)
            self.isOpen = false
            self.state.removeAll()?.fail(error)
            assert(self.state.isEmpty)
            switch self.outboundCloseState {
            case .open, .closed:
                self.outboundCloseState = .closed
            case .pending(let closePromise), .readyForClose(let closePromise):
                closePromise?.fail(error)
                self.outboundCloseState = .closed
            }
        }
    }

    /// Signal the intention to close. Takes a promise which MUST be completed via a call to `closeComplete`
    ///
    /// - Parameters:
    ///   - promise: Optionally an `EventLoopPromise` that will be succeeded once all outstanding writes have been dealt with
    func close(_ promise: EventLoopPromise<Void>?) -> CloseResult {
        assert(self.isOpen)

        if self.isEmpty {
            switch self.outboundCloseState {
            case .open:
                self.outboundCloseState = .readyForClose(promise)
            case .readyForClose(var closePromise), .pending(var closePromise):
                closePromise.setOrCascade(to: promise)
                self.outboundCloseState = .readyForClose(closePromise)

Review comment (bug):
Not sure if it's just the diff but it looks like this function also failed all the promises if `!close`, that doesn't seem to happen anymore.

Code after:
    /// - Parameters:
    ///   - operation: The vector write operation to use. Usually `writev`.
    private func triggerVectorBufferWrite(
        _ operation: (UnsafeBufferPointer<IOVector>) throws -> IOResult<Int>
    ) throws -> OneWriteOperationResult {
        assert(
            self.state.isFlushPending && !self.state.isEmpty && self.isOpen,
            "vector write called in illegal state: flush pending: \(self.state.isFlushPending), empty: \(self.state.isEmpty), isOpen: \(self.isOpen)"
        )
        let result = try doPendingWriteVectorOperation(
            pending: self.state,
            bufferPool: bufferPool,
            { try operation($0) }
        )
        return self.didWrite(itemCount: result.itemCount, result: result.writeResult)
    }

    /// Fail all the outstanding writes.
    func failAll(error: Error) -> EventLoopPromise<Void>? {
        assert(self.isOpen)

        let promise: EventLoopPromise<Void>?
        self.isOpen = false
        switch self.outboundCloseState {
        case .open, .closed:
            self.outboundCloseState = .closed
            promise = nil
        case .pending(let closePromise), .readyForClose(let closePromise):
            self.outboundCloseState = .closed
            promise = closePromise
        }

        self.state.removeAll()?.fail(error)

        assert(self.state.isEmpty)
        return promise
    }

    // The result of calling `closeOutbound`
    enum CloseOutboundResult {
        case pending
        case readyForClose(EventLoopPromise<Void>?)
        case closed(EventLoopPromise<Void>?)
        case errored(Error, EventLoopPromise<Void>?)

        init(_ closeState: CloseState, _ isEmpty: Bool, _ promise: EventLoopPromise<Void>?) {
            switch closeState {
            case .open:
                assertionFailure(
                    "We are in .open state after being asked to close. This should never happen."
                )