MapAsync wouldn't complete when upstream does in all scenarios #28657
This commit is contained in:
parent
e6ee6ee4e0
commit
3157b0199b
3 changed files with 84 additions and 9 deletions
|
|
@ -1315,10 +1315,8 @@ private[stream] object Collect {
|
|||
|
||||
@tailrec
|
||||
private def pushNextIfPossible(): Unit =
|
||||
if (buffer.isEmpty) {
|
||||
if (isClosed(in)) completeStage()
|
||||
else pullIfNeeded()
|
||||
} else if (buffer.peek().elem eq NotYetThere) pullIfNeeded() // ahead of line blocking to keep order
|
||||
if (buffer.isEmpty) pullIfNeeded()
|
||||
else if (buffer.peek().elem eq NotYetThere) pullIfNeeded() // ahead of line blocking to keep order
|
||||
else if (isAvailable(out)) {
|
||||
val holder = buffer.dequeue()
|
||||
holder.elem match {
|
||||
|
|
@ -1343,7 +1341,9 @@ private[stream] object Collect {
|
|||
}
|
||||
|
||||
private def pullIfNeeded(): Unit = {
|
||||
if (buffer.used < parallelism && !hasBeenPulled(in)) tryPull(in)
|
||||
if (isClosed(in) && buffer.isEmpty) completeStage()
|
||||
else if (buffer.used < parallelism && !hasBeenPulled(in)) tryPull(in)
|
||||
// else already pulled and waiting for next element
|
||||
}
|
||||
|
||||
setHandlers(in, out, this)
|
||||
|
|
@ -1378,19 +1378,21 @@ private[stream] object Collect {
|
|||
override def preStart(): Unit = buffer = BufferImpl(parallelism, inheritedAttributes)
|
||||
|
||||
def futureCompleted(result: Try[Out]): Unit = {
|
||||
def isCompleted = isClosed(in) && todo == 0
|
||||
inFlight -= 1
|
||||
result match {
|
||||
case Success(elem) if elem != null =>
|
||||
if (isAvailable(out)) {
|
||||
if (!hasBeenPulled(in)) tryPull(in)
|
||||
push(out, elem)
|
||||
if (isCompleted) completeStage()
|
||||
} else buffer.enqueue(elem)
|
||||
case Success(null) =>
|
||||
if (isClosed(in) && todo == 0) completeStage()
|
||||
if (isCompleted) completeStage()
|
||||
else if (!hasBeenPulled(in)) tryPull(in)
|
||||
case Failure(ex) =>
|
||||
if (decider(ex) == Supervision.Stop) failStage(ex)
|
||||
else if (isClosed(in) && todo == 0) completeStage()
|
||||
else if (isCompleted) completeStage()
|
||||
else if (!hasBeenPulled(in)) tryPull(in)
|
||||
}
|
||||
}
|
||||
|
|
@ -1418,9 +1420,10 @@ private[stream] object Collect {
|
|||
|
||||
override def onPull(): Unit = {
|
||||
if (!buffer.isEmpty) push(out, buffer.dequeue())
|
||||
else if (isClosed(in) && todo == 0) completeStage()
|
||||
|
||||
if (todo < parallelism && !hasBeenPulled(in)) tryPull(in)
|
||||
val leftTodo = todo
|
||||
if (isClosed(in) && leftTodo == 0) completeStage()
|
||||
else if (leftTodo < parallelism && !hasBeenPulled(in)) tryPull(in)
|
||||
}
|
||||
|
||||
setHandlers(in, out, this)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue