diff --git a/Sources/NIOCore/AsyncSequences/NIOAsyncSequenceProducerStrategies.swift b/Sources/NIOCore/AsyncSequences/NIOAsyncSequenceProducerStrategies.swift index 6de186197c..abed4fd870 100644 --- a/Sources/NIOCore/AsyncSequences/NIOAsyncSequenceProducerStrategies.swift +++ b/Sources/NIOCore/AsyncSequences/NIOAsyncSequenceProducerStrategies.swift @@ -37,29 +37,20 @@ public enum NIOAsyncSequenceProducerBackPressureStrategies { public mutating func didYield(bufferDepth: Int) -> Bool { // We are demanding more until we reach the high watermark - if bufferDepth < self.highWatermark { - precondition(self.hasOustandingDemand) - return true - } else { + if bufferDepth >= self.highWatermark { self.hasOustandingDemand = false - return false } + + return self.hasOustandingDemand } public mutating func didConsume(bufferDepth: Int) -> Bool { // We start demanding again once we are below the low watermark if bufferDepth < self.lowWatermark { - if self.hasOustandingDemand { - // We are below and have outstanding demand - return true - } else { - // We are below but don't have outstanding demand but need more - self.hasOustandingDemand = true - return true - } - } else { - return self.hasOustandingDemand + self.hasOustandingDemand = true } + + return self.hasOustandingDemand } } } diff --git a/Tests/NIOCoreTests/AsyncSequences/NIOAsyncSequenceProducer+HighLowWatermarkBackPressureStrategyTests.swift b/Tests/NIOCoreTests/AsyncSequences/NIOAsyncSequenceProducer+HighLowWatermarkBackPressureStrategyTests.swift index f7a6790ecf..cd7c738f98 100644 --- a/Tests/NIOCoreTests/AsyncSequences/NIOAsyncSequenceProducer+HighLowWatermarkBackPressureStrategyTests.swift +++ b/Tests/NIOCoreTests/AsyncSequences/NIOAsyncSequenceProducer+HighLowWatermarkBackPressureStrategyTests.swift @@ -57,4 +57,15 @@ final class NIOAsyncSequenceProducerBackPressureStrategiesHighLowWatermarkTests: func testDidConsume_whenAtLowWatermark() { XCTAssertTrue(self.strategy.didConsume(bufferDepth: 5)) } + + func testDidYieldWhenNoOutstandingDemand() { + // Hit the high watermark + XCTAssertFalse(self.strategy.didYield(bufferDepth: 10)) + // Drop below it, don't read. + XCTAssertFalse(self.strategy.didConsume(bufferDepth: 7)) + // Yield more, still above the low watermark, so don't produce more. + XCTAssertFalse(self.strategy.didYield(bufferDepth: 8)) + // Drop below low watermark to start producing again. + XCTAssertTrue(self.strategy.didConsume(bufferDepth: 4)) + } }