migrating Doubler, KeepGoing to GraphStage

This commit is contained in:
zhxiaog 2016-04-14 00:37:15 +08:00
parent a1423b6e7d
commit 16ac832b14
2 changed files with 64 additions and 36 deletions

View file

@ -132,7 +132,7 @@ class HttpServerExampleSpec extends WordSpec with Matchers
"connection-stream-failure-handling" in compileOnlySpec { "connection-stream-failure-handling" in compileOnlySpec {
import akka.actor.ActorSystem import akka.actor.ActorSystem
import akka.http.scaladsl.Http import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{ContentTypes, HttpEntity} import akka.http.scaladsl.model.{ ContentTypes, HttpEntity }
import akka.stream.ActorMaterializer import akka.stream.ActorMaterializer
implicit val system = ActorSystem() implicit val system = ActorSystem()

View file

@ -8,7 +8,7 @@ import akka.stream.stage._
import akka.testkit.AkkaSpec import akka.testkit.AkkaSpec
import akka.testkit.EventFilter import akka.testkit.EventFilter
import akka.stream.Supervision import akka.stream._
class InterpreterSpec extends AkkaSpec with GraphInterpreterSpecKit { class InterpreterSpec extends AkkaSpec with GraphInterpreterSpecKit {
import Supervision.stoppingDecider import Supervision.stoppingDecider
@ -80,7 +80,7 @@ class InterpreterSpec extends AkkaSpec with GraphInterpreterSpecKit {
} }
"implement one-to-many many-to-one chain correctly" in new OneBoundedSetup[Int]( "implement one-to-many many-to-one chain correctly" in new OneBoundedSetup[Int](
Doubler().toGS, Doubler(),
Filter((x: Int) x != 0)) { Filter((x: Int) x != 0)) {
lastEvents() should be(Set.empty) lastEvents() should be(Set.empty)
@ -106,7 +106,7 @@ class InterpreterSpec extends AkkaSpec with GraphInterpreterSpecKit {
"implement many-to-one one-to-many chain correctly" in new OneBoundedSetup[Int]( "implement many-to-one one-to-many chain correctly" in new OneBoundedSetup[Int](
Filter((x: Int) x != 0), Filter((x: Int) x != 0),
Doubler().toGS) { Doubler()) {
lastEvents() should be(Set.empty) lastEvents() should be(Set.empty)
@ -412,7 +412,7 @@ class InterpreterSpec extends AkkaSpec with GraphInterpreterSpecKit {
} }
"implement doubler-conflate (doubler-batch)" in new OneBoundedSetup[Int]( "implement doubler-conflate (doubler-batch)" in new OneBoundedSetup[Int](
Doubler().toGS, Doubler(),
Batch( Batch(
1L, 1L,
ConstantFun.zeroLong, ConstantFun.zeroLong,
@ -432,12 +432,12 @@ class InterpreterSpec extends AkkaSpec with GraphInterpreterSpecKit {
} }
// Note, the new interpreter has no jumpback table, still did not want to remove the test // 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](Seq( "work with jumpback table and completed elements" in new OneBoundedSetup[Int](
Map((x: Int) x, stoppingDecider), Map((x: Int) x, stoppingDecider).toGS,
Map((x: Int) x, stoppingDecider), Map((x: Int) x, stoppingDecider).toGS,
KeepGoing(), KeepGoing(),
Map((x: Int) x, stoppingDecider), Map((x: Int) x, stoppingDecider).toGS,
Map((x: Int) x, stoppingDecider))) { Map((x: Int) x, stoppingDecider).toGS) {
lastEvents() should be(Set.empty) lastEvents() should be(Set.empty)
@ -569,39 +569,67 @@ class InterpreterSpec extends AkkaSpec with GraphInterpreterSpecKit {
} }
private[akka] case class Doubler[T]() extends PushPullStage[T, T] { private[akka] final case class Doubler[T]() extends GraphStage[FlowShape[T, T]] {
var oneMore: Boolean = false val out: Outlet[T] = Outlet("Doubler.out")
var lastElem: T = _ val in: Inlet[T] = Inlet("Doubler.in")
override def onPush(elem: T, ctx: Context[T]): SyncDirective = { override def createLogic(inheritedAttributes: Attributes): GraphStageLogic =
lastElem = elem new GraphStageLogic(shape) with InHandler with OutHandler {
oneMore = true var latest: T = _
ctx.push(elem) var oneMore = false
}
override def onPull(ctx: Context[T]): SyncDirective = { override def onPush(): Unit = {
if (oneMore) { latest = grab(in)
oneMore = false oneMore = true
ctx.push(lastElem) push(out, latest)
} else ctx.pull() }
}
/**
* Called when the output port has received a pull, and therefore ready to emit an element, i.e. [[GraphStageLogic.push()]]
* is now allowed to be called on this port.
*/
override def onPull(): Unit = {
if (oneMore) {
push(out, latest)
oneMore = false
} else {
pull(in)
}
}
setHandlers(in, out, this)
}
override val shape: FlowShape[T, T] = FlowShape(in, out)
} }
private[akka] case class KeepGoing[T]() extends PushPullStage[T, T] { private[akka] final case class KeepGoing[T]() extends GraphStage[FlowShape[T, T]] {
var lastElem: T = _ val in = Inlet[T]("KeepGoing.in")
val out = Outlet[T]("KeepGoing.out")
override def onPush(elem: T, ctx: Context[T]): SyncDirective = { override def createLogic(inheritedAttributes: Attributes): GraphStageLogic =
lastElem = elem new GraphStageLogic(shape) with InHandler with OutHandler {
ctx.push(elem) var lastElem: T = _
}
override def onPull(ctx: Context[T]): SyncDirective = { override def onPush(): Unit = {
if (ctx.isFinishing) { lastElem = grab(in)
ctx.push(lastElem) push(out, lastElem)
} else ctx.pull() }
}
override def onUpstreamFinish(ctx: Context[T]): TerminationDirective = ctx.absorbTermination() override def onPull(): Unit = {
if (isClosed(in)) {
push(out, lastElem)
} else {
pull(in)
}
}
override def onUpstreamFinish(): Unit = {}
setHandlers(in, out, this)
}
override val shape: FlowShape[T, T] = FlowShape(in, out)
} }
// This test is related to issue #17351 // This test is related to issue #17351