@@ -21,7 +21,6 @@ import scala.annotation.tailrec
21
21
import scala .collection .{ immutable , mutable }
22
22
import scala .concurrent .{ Future , Promise }
23
23
import scala .concurrent .duration .FiniteDuration
24
-
25
24
import org .apache .pekko
26
25
import pekko .{ Done , NotUsed }
27
26
import pekko .actor ._
@@ -37,6 +36,8 @@ import pekko.stream.stage.ConcurrentAsyncCallbackState.{ NoPendingEvents, State
37
36
import pekko .util .OptionVal
38
37
import pekko .util .unused
39
38
39
+ import java .util .Spliterator
40
+
40
41
/**
41
42
* Scala API: A GraphStage represents a reusable graph stream processing operator.
42
43
*
@@ -979,6 +980,26 @@ abstract class GraphStageLogic private[stream] (val inCount: Int, val outCount:
979
980
}
980
981
} else andThen()
981
982
983
+ /**
984
+ * Emit a sequence of elements through the given outlet and continue with the given thunk
985
+ * afterwards, suspending execution if necessary.
986
+ * This action replaces the [[OutHandler ]] for the given outlet if suspension
987
+ * is needed and reinstalls the current handler upon receiving an `onPull()`
988
+ * signal (before invoking the `andThen` function).
989
+ */
990
+ final protected def emitMultiple [T ](out : Outlet [T ], elems : Spliterator [T ], andThen : () => Unit ): Unit = {
991
+ val iter = new EmittingSpliterator [T ](out, elems, getNonEmittingHandler(out), andThen)
992
+ if (isAvailable(out)) {
993
+ if (! iter.tryPush()) {
994
+ andThen()
995
+ } else {
996
+ setOrAddEmitting(out, iter)
997
+ }
998
+ } else {
999
+ setOrAddEmitting(out, iter)
1000
+ }
1001
+ }
1002
+
982
1003
/**
983
1004
* Emit a sequence of elements through the given outlet, suspending execution if necessary.
984
1005
* This action replaces the [[OutHandler ]] for the given outlet if suspension
@@ -1118,6 +1139,19 @@ abstract class GraphStageLogic private[stream] (val inCount: Int, val outCount:
1118
1139
}
1119
1140
}
1120
1141
1142
+ private final class EmittingSpliterator [T ](_out : Outlet [T ], elems : Spliterator [T ], _previous : OutHandler ,
1143
+ _andThen : () => Unit )
1144
+ extends Emitting [T ](_out, _previous, _andThen) with java.util.function.Consumer [T ] {
1145
+
1146
+ override def onPull (): Unit = if (! elems.tryAdvance(this )) {
1147
+ followUp()
1148
+ }
1149
+
1150
+ def tryPush (): Boolean = elems.tryAdvance(this )
1151
+
1152
+ override def accept (elem : T ): Unit = push(out, elem)
1153
+ }
1154
+
1121
1155
private class EmittingCompletion [T ](_out : Outlet [T ], _previous : OutHandler )
1122
1156
extends Emitting [T ](_out, _previous, DoNothing ) {
1123
1157
override def onPull (): Unit = complete(out)
0 commit comments