stream: filter out elements without demand
This will also mean that completion will not be blocked by elements that will later be filtered out. One particular use case of that would be a kind of partitioning use case, where you put several streams behind a broadcast and each consumer will filter out elements not handled there. In that case, the broadcast can get head-of-line blocked when one of the consumers currently has no demand but also wouldn't have to handle any elements because they would all be filtered out.
This commit is contained in:
parent
b30f8746d3
commit
c39dd6506e
3 changed files with 66 additions and 21 deletions
|
|
@ -79,14 +79,19 @@ import com.github.ghik.silencer.silent
|
|||
new GraphStageLogic(shape) with OutHandler with InHandler {
|
||||
def decider = inheritedAttributes.mandatoryAttribute[SupervisionStrategy].decider
|
||||
|
||||
override def onPush(): Unit = {
|
||||
private var buffer: OptionVal[T] = OptionVal.none
|
||||
|
||||
override def preStart(): Unit = pull(in)
|
||||
override def onPush(): Unit =
|
||||
try {
|
||||
val elem = grab(in)
|
||||
if (p(elem)) {
|
||||
push(out, elem)
|
||||
} else {
|
||||
pull(in)
|
||||
}
|
||||
if (p(elem))
|
||||
if (isAvailable(out)) {
|
||||
push(out, elem)
|
||||
pull(in)
|
||||
} else
|
||||
buffer = OptionVal.Some(elem)
|
||||
else pull(in)
|
||||
} catch {
|
||||
case NonFatal(ex) =>
|
||||
decider(ex) match {
|
||||
|
|
@ -94,9 +99,20 @@ import com.github.ghik.silencer.silent
|
|||
case _ => pull(in)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override def onPull(): Unit = pull(in)
|
||||
override def onPull(): Unit =
|
||||
buffer match {
|
||||
case OptionVal.Some(value) =>
|
||||
push(out, value)
|
||||
buffer = OptionVal.none
|
||||
if (!isClosed(in)) pull(in)
|
||||
else completeStage()
|
||||
case _ => // already pulled
|
||||
}
|
||||
|
||||
override def onUpstreamFinish(): Unit =
|
||||
if (buffer.isEmpty) super.onUpstreamFinish()
|
||||
// else onPull will complete
|
||||
|
||||
setHandlers(in, out, this)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue