make Map a GraphStage

This commit is contained in:
Endre Sándor Varga 2016-07-20 13:26:27 +02:00
parent b498347933
commit 5382014133
10 changed files with 108 additions and 75 deletions

View file

@ -7,8 +7,8 @@ import akka.stream.impl.ConstantFun
import akka.stream.stage._
import akka.stream.testkit.StreamSpec
import akka.testkit.EventFilter
import akka.stream._
import akka.stream.impl.fusing.GraphStages.SimpleLinearGraphStage
class InterpreterSpec extends StreamSpec with GraphInterpreterSpecKit {
import Supervision.stoppingDecider
@ -24,7 +24,7 @@ class InterpreterSpec extends StreamSpec with GraphInterpreterSpecKit {
"Interpreter" must {
"implement map correctly" in new OneBoundedSetup[Int](Seq(Map((x: Int) x + 1, stoppingDecider))) {
"implement map correctly" in new OneBoundedSetup[Int](Map((x: Int) x + 1)) {
lastEvents() should be(Set.empty)
downstream.requestOne()
@ -43,10 +43,10 @@ class InterpreterSpec extends StreamSpec with GraphInterpreterSpecKit {
lastEvents() should be(Set(OnComplete))
}
"implement chain of maps correctly" in new OneBoundedSetup[Int](Seq(
Map((x: Int) x + 1, stoppingDecider),
Map((x: Int) x * 2, stoppingDecider),
Map((x: Int) x + 1, stoppingDecider))) {
"implement chain of maps correctly" in new OneBoundedSetup[Int](
Map((x: Int) x + 1),
Map((x: Int) x * 2),
Map((x: Int) x + 1)) {
lastEvents() should be(Set.empty)
@ -66,7 +66,7 @@ class InterpreterSpec extends StreamSpec with GraphInterpreterSpecKit {
lastEvents() should be(Set(Cancel))
}
"work with only boundary ops" in new OneBoundedSetup[Int](Seq.empty) {
"work with only boundary ops" in new OneBoundedSetup[Int]() {
lastEvents() should be(Set.empty)
downstream.requestOne()
@ -149,7 +149,7 @@ class InterpreterSpec extends StreamSpec with GraphInterpreterSpecKit {
"implement take inside a chain" in new OneBoundedSetup[Int](
Filter((x: Int) x != 0),
takeTwo,
Map((x: Int) x + 1, stoppingDecider).toGS) {
Map((x: Int) x + 1)) {
lastEvents() should be(Set.empty)
@ -433,11 +433,11 @@ class InterpreterSpec extends StreamSpec with GraphInterpreterSpecKit {
// Note, the new interpreter has no jumpback table, still did not want to remove the test
"work with jumpback table and completed elements" in new OneBoundedSetup[Int](
Map((x: Int) x, stoppingDecider).toGS,
Map((x: Int) x, stoppingDecider).toGS,
Map((x: Int) x),
Map((x: Int) x),
KeepGoing(),
Map((x: Int) x, stoppingDecider).toGS,
Map((x: Int) x, stoppingDecider).toGS) {
Map((x: Int) x),
Map((x: Int) x)) {
lastEvents() should be(Set.empty)
@ -464,8 +464,7 @@ class InterpreterSpec extends StreamSpec with GraphInterpreterSpecKit {
}
"work with pushAndFinish if upstream completes with pushAndFinish" in new OneBoundedSetup[Int](Seq(
new PushFinishStage)) {
"work with pushAndFinish if upstream completes with pushAndFinish" in new OneBoundedSetup[Int](new PushFinishStage) {
lastEvents() should be(Set.empty)
@ -476,10 +475,10 @@ class InterpreterSpec extends StreamSpec with GraphInterpreterSpecKit {
lastEvents() should be(Set(OnNext(0), OnComplete))
}
"work with pushAndFinish if indirect upstream completes with pushAndFinish" in new OneBoundedSetup[Int](Seq(
Map((x: Any) x, stoppingDecider),
"work with pushAndFinish if indirect upstream completes with pushAndFinish" in new OneBoundedSetup[Int](
Map((x: Any) x),
new PushFinishStage,
Map((x: Any) x, stoppingDecider))) {
Map((x: Any) x)) {
lastEvents() should be(Set.empty)
@ -491,7 +490,7 @@ class InterpreterSpec extends StreamSpec with GraphInterpreterSpecKit {
}
"work with pushAndFinish if upstream completes with pushAndFinish and downstream immediately pulls" in new OneBoundedSetup[Int](
(new PushFinishStage).toGS,
new PushFinishStage,
Fold(0, (x: Int, y: Int) x + y)) {
lastEvents() should be(Set.empty)
@ -503,11 +502,18 @@ class InterpreterSpec extends StreamSpec with GraphInterpreterSpecKit {
lastEvents() should be(Set(OnNext(1), OnComplete))
}
"report error if pull is called while op is terminating" in new OneBoundedSetup[Int](Seq(new PushPullStage[Any, Any] {
override def onPull(ctx: Context[Any]): SyncDirective = ctx.pull()
override def onPush(elem: Any, ctx: Context[Any]): SyncDirective = ctx.pull()
override def onUpstreamFinish(ctx: Context[Any]): TerminationDirective = ctx.absorbTermination()
})) {
"report error if pull is called while op is terminating" in new OneBoundedSetup[Int](
new SimpleLinearGraphStage[Any] {
override def createLogic(inheritedAttributes: Attributes): GraphStageLogic =
new GraphStageLogic(shape) with InHandler with OutHandler {
override def onPush(): Unit = pull(in)
override def onPull(): Unit = pull(in)
override def onUpstreamFinish(): Unit = if (!hasBeenPulled(in)) pull(in)
setHandlers(in, out, this)
}
}
) {
lastEvents() should be(Set.empty)
downstream.requestOne()
@ -558,8 +564,8 @@ class InterpreterSpec extends StreamSpec with GraphInterpreterSpecKit {
override def onDownstreamFinish(ctx: Context[Int]): TerminationDirective = ctx.absorbTermination()
}
"not allow absorbTermination from onDownstreamFinish()" in new OneBoundedSetup[Int](Seq(
new InvalidAbsorbTermination)) {
// This test must be kept since it tests the compatibility layer, which while is deprecated it is still here.
"not allow absorbTermination from onDownstreamFinish()" in new OneBoundedSetup[Int]((new InvalidAbsorbTermination).toGS) {
lastEvents() should be(Set.empty)
EventFilter[UnsupportedOperationException]("It is not allowed to call absorbTermination() from onDownstreamFinish.", occurrences = 1).intercept {
@ -635,16 +641,19 @@ class InterpreterSpec extends StreamSpec with GraphInterpreterSpecKit {
override val shape: FlowShape[T, T] = FlowShape(in, out)
}
// This test is related to issue #17351
private[akka] class PushFinishStage(onPostStop: () Unit = () ()) extends PushStage[Any, Any] {
override def onPush(elem: Any, ctx: Context[Any]): SyncDirective =
ctx.pushAndFinish(elem)
private[akka] class PushFinishStage(onPostStop: () Unit = () ()) extends SimpleLinearGraphStage[Any] {
override def createLogic(inheritedAttributes: Attributes): GraphStageLogic =
new GraphStageLogic(shape) with InHandler with OutHandler {
override def onPush(): Unit = {
push(out, grab(in))
completeStage()
}
override def onPull(): Unit = pull(in)
override def onUpstreamFinish(): Unit = failStage(akka.stream.testkit.Utils.TE("Cannot happen"))
override def postStop(): Unit = onPostStop()
override def onUpstreamFinish(ctx: Context[Any]): TerminationDirective =
ctx.fail(akka.stream.testkit.Utils.TE("Cannot happen"))
override def postStop(): Unit =
onPostStop()
setHandlers(in, out, this)
}
}
}