pekko/akka-docs/src/test/scala/docs/stream/ActorPublisherDocSpec.scala

97 lines
2.3 KiB
Scala
Raw Normal View History

2014-12-19 15:22:45 +01:00
/**
2017-01-04 17:37:10 +01:00
* Copyright (C) 2014-2017 Lightbend Inc. <http://www.lightbend.com>
2014-12-19 15:22:45 +01:00
*/
package docs.stream
import scala.annotation.tailrec
import akka.actor.Props
import akka.stream.ActorMaterializer
2014-12-19 15:22:45 +01:00
import akka.stream.actor.ActorPublisher
import akka.stream.scaladsl.{ Flow, Sink, Source }
import akka.testkit.AkkaSpec
2014-12-19 15:22:45 +01:00
object ActorPublisherDocSpec {
//#job-manager
object JobManager {
def props: Props = Props[JobManager]
final case class Job(payload: String)
case object JobAccepted
case object JobDenied
}
class JobManager extends ActorPublisher[JobManager.Job] {
import akka.stream.actor.ActorPublisherMessage._
import JobManager._
val MaxBufferSize = 100
var buf = Vector.empty[Job]
def receive = {
2017-10-06 10:30:28 +02:00
case job: Job if buf.size == MaxBufferSize
2014-12-19 15:22:45 +01:00
sender() ! JobDenied
2017-10-06 10:30:28 +02:00
case job: Job
2014-12-19 15:22:45 +01:00
sender() ! JobAccepted
if (buf.isEmpty && totalDemand > 0)
onNext(job)
else {
buf :+= job
deliverBuf()
}
2017-10-06 10:30:28 +02:00
case Request(_)
2014-12-19 15:22:45 +01:00
deliverBuf()
2017-10-06 10:30:28 +02:00
case Cancel
2014-12-19 15:22:45 +01:00
context.stop(self)
}
@tailrec final def deliverBuf(): Unit =
if (totalDemand > 0) {
2014-12-20 16:56:22 +01:00
/*
* totalDemand is a Long and could be larger than
* what buf.splitAt can accept
*/
2014-12-19 15:22:45 +01:00
if (totalDemand <= Int.MaxValue) {
val (use, keep) = buf.splitAt(totalDemand.toInt)
buf = keep
use foreach onNext
} else {
val (use, keep) = buf.splitAt(Int.MaxValue)
buf = keep
use foreach onNext
deliverBuf()
}
}
}
//#job-manager
}
class ActorPublisherDocSpec extends AkkaSpec {
import ActorPublisherDocSpec._
implicit val materializer = ActorMaterializer()
2014-12-19 15:22:45 +01:00
"illustrate usage of ActorPublisher" in {
def println(s: String): Unit =
testActor ! s
//#actor-publisher-usage
val jobManagerSource = Source.actorPublisher[JobManager.Job](JobManager.props)
val ref = Flow[JobManager.Job]
2014-12-19 15:22:45 +01:00
.map(_.payload.toUpperCase)
2017-10-06 10:30:28 +02:00
.map { elem println(elem); elem }
2014-12-19 15:22:45 +01:00
.to(Sink.ignore)
.runWith(jobManagerSource)
2014-12-19 15:22:45 +01:00
ref ! JobManager.Job("a")
ref ! JobManager.Job("b")
ref ! JobManager.Job("c")
//#actor-publisher-usage
expectMsg("A")
expectMsg("B")
expectMsg("C")
}
}