akka.actor.typed.Behavior Scala Examples
The following examples show how to use akka.actor.typed.Behavior.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example.
Example 1
Source File: ShardStateTracker.scala From Pi-Akka-Cluster with Apache License 2.0 | 5 votes |
package com.lightbend.akka_oled import akka.actor.typed.{ActorRef, Behavior} import akka.actor.typed.scaladsl.Behaviors import akka.cluster.sharding.ShardRegion.CurrentShardRegionState import akka.cluster.sharding.typed.{ClusterShardingQuery, GetShardRegionState} import akka.util.Timeout import com.lightbend.akka_oled.OledShardingVisualizer.ShardRegionState import scala.concurrent.duration._ object ShardStateTracker { implicit val timeout: Timeout = 6.seconds def apply(visualizer: ActorRef[OledShardingVisualizer.Command]): Behavior[CurrentShardRegionState] = Behaviors.setup { context => Behaviors.receiveMessage { message: CurrentShardRegionState => visualizer.tell(ShardRegionState(message.shards)) Behaviors.same } } } object ShardStateScheduler { implicit val timeout: Timeout = 6.seconds case class Tick() def apply(shardState: ActorRef[ClusterShardingQuery], shardTracker: ActorRef[CurrentShardRegionState]): Behavior[Tick] = Behaviors.withTimers { timer => timer.startTimerAtFixedRate(Tick(), 1.second) Behaviors.receiveMessage { _: Tick => shardState ! GetShardRegionState(ClientEntity.TypeKey, shardTracker) Behaviors.same } } }
Example 2
Source File: LoadGenerator.scala From akka-persistence-cassandra with Apache License 2.0 | 5 votes |
package akka.persistence.cassandra.example import akka.actor.typed.{ ActorRef, Behavior } import akka.actor.typed.scaladsl.Behaviors import akka.cluster.sharding.typed.ShardingEnvelope import com.typesafe.config.Config import scala.concurrent.duration.FiniteDuration import scala.util.Random import akka.util.JavaDurationConverters._ object LoadGenerator { object Settings { def apply(config: Config): Settings = { Settings(config.getInt("persistence-ids"), config.getDuration("load-tick-duration").asScala) } } case class Settings(nrPersistenceIds: Int, tickDuration: FiniteDuration) sealed trait Command final case class Start(duration: FiniteDuration) extends Command final case class Tick() extends Command private case object Stop extends Command def apply( settings: Settings, ref: ActorRef[ShardingEnvelope[ConfigurablePersistentActor.Event]]): Behavior[Command] = { Behaviors.withTimers { timers => Behaviors.setup { ctx => Behaviors.receiveMessage { case Start(duration) => ctx.log.info("Starting...") timers.startTimerAtFixedRate(Tick(), settings.tickDuration) timers.startSingleTimer(Stop, duration) Behaviors.same case Tick() => ctx.log.info("Sending event") ref ! ShardingEnvelope( s"p${Random.nextInt(settings.nrPersistenceIds)}", ConfigurablePersistentActor.Event()) Behaviors.same case Stop => Behaviors.same } } } } }
Example 3
Source File: ForkJoinThroughput.scala From effpi with MIT License | 5 votes |
// Effpi - verified message-passing programs in Dotty // Copyright 2019 Alceste Scalas and Elias Benussi // Released under the MIT License: https://opensource.org/licenses/MIT package effpi.benchmarks.akka import akka.NotUsed import akka.actor.typed.scaladsl.{ Behaviors, MutableBehavior, ActorContext} import akka.actor.typed.{ ActorRef, ActorSystem, Behavior, DispatcherSelector, Terminated } import scala.concurrent.Future import scala.concurrent.duration._ import scala.concurrent.{ Future, Promise, Await } import scala.concurrent.ExecutionContext.Implicits.global object ForkJoinThroughput { case class Message(msg: String) def receiver(maxMsgs: Int) = Behaviors.setup[Message] { ctx => new MutableSimpleActor(ctx, maxMsgs) } class MutableSimpleActor( ctx: ActorContext[Message], maxMsgs: Int ) extends MutableBehavior[Message] { var count = 0 override def onMessage(msg: Message): Behavior[Message] = { count +=1 if (count < maxMsgs) { Behaviors.same } else { Behaviors.stopped } } } def mainActor( durationPromise: Promise[Long], numActors: Int, numMessages: Int ): Behavior[akka.NotUsed] = Behaviors.setup { ctx => val receiversRef = (1 to numActors).map{ id => ctx.spawn(receiver(numMessages), "receiver" + id)} val startTime = System.nanoTime() (1 to numMessages).foreach { n => receiversRef.foreach { simpleActor => simpleActor ! Message("Hello World!") } } val endTime = System.nanoTime() durationPromise.success(endTime - startTime) Behaviors.stopped } def bench(params: (Int, Int)): Long = { val (numActors, numMessages) = params val durationPromise = Promise[Long]() val durationFuture = durationPromise.future val system = ActorSystem( mainActor(durationPromise, numActors, numMessages), "ForkJoinCreationDemo") Await.result(system.whenTerminated, Duration.Inf) val duration = Await.result(durationFuture, Duration.Inf) duration } }
Example 4
Source File: CountingActor.scala From effpi with MIT License | 5 votes |
// Effpi - verified message-passing programs in Dotty // Copyright 2019 Alceste Scalas and Elias Benussi // Released under the MIT License: https://opensource.org/licenses/MIT package effpi.benchmarks.akka import akka.NotUsed import akka.actor.typed.scaladsl.{ Behaviors, MutableBehavior, ActorContext} import akka.actor.typed.{ ActorRef, ActorSystem, Behavior, DispatcherSelector, Terminated } import scala.concurrent.Future import scala.concurrent.duration._ import scala.concurrent.{ Future, Promise, Await } import scala.concurrent.ExecutionContext.Implicits.global object CountingActor { sealed trait CounterAction object CounterAction { final case class Add(num: Int, p: Promise[Int]) extends CounterAction final case class Cheque(replyTo: ActorRef[Sum]) extends CounterAction } case class Sum(sum: Int) val counter = Behaviors.setup[CounterAction] { ctx => new MutableCounter(ctx) } class MutableCounter( ctx: ActorContext[CounterAction] ) extends MutableBehavior[CounterAction] { var counter = 0 override def onMessage(msg: CounterAction): Behavior[CounterAction] = { msg match { case CounterAction.Add(num, p) => counter += 1 p.success(num) Behaviors.same case CounterAction.Cheque(replyTo) => replyTo ! Sum(counter) Behaviors.stopped } } } def sink(endTimePromise: Promise[Long]) = Behaviors.receive[Sum] { (ctx, msg) => endTimePromise.success(System.nanoTime()) Behaviors.stopped } def mainActor( durationPromise: Promise[Long], numMessages: Int ): Behavior[akka.NotUsed] = Behaviors.setup { ctx => val endTimePromise = Promise[Long]() val endTimeFuture = endTimePromise.future val sinkRef = ctx.spawn(sink(endTimePromise), "sink") ctx.watch(sinkRef) val counterRef = ctx.spawn(counter, "counter") val startTime = System.nanoTime() val futs = (1 to numMessages).toList.map { num => val p = Promise[Int]() val f = p.future counterRef ! CounterAction.Add(num, p) f } Await.result(Future.sequence(futs), Duration.Inf) counterRef ! CounterAction.Cheque(sinkRef) val endTime = Await.result(endTimeFuture, Duration.Inf) val countingDuration = endTime - startTime durationPromise.success(countingDuration) Behaviors.receiveSignal { case (_, Terminated(ref)) => Behaviors.stopped case (_, _) => Behaviors.empty } } def bench(params: Int): Long = { val durationPromise = Promise[Long]() val durationFuture = durationPromise.future val system = ActorSystem( mainActor(durationPromise, params), "CountingActorDemo") Await.result(system.whenTerminated, Duration.Inf) val duration = Await.result(durationFuture, Duration.Inf) duration } }
Example 5
Source File: PingPong.scala From effpi with MIT License | 5 votes |
// Effpi - verified message-passing programs in Dotty // Copyright 2019 Alceste Scalas and Elias Benussi // Released under the MIT License: https://opensource.org/licenses/MIT package effpi.benchmarks.akka import akka.NotUsed import akka.actor.typed.scaladsl.{ Behaviors, MutableBehavior, ActorContext} import akka.actor.typed.{ ActorRef, ActorSystem, Behavior, DispatcherSelector, Terminated } import scala.concurrent.Future import scala.concurrent.duration._ import scala.concurrent.{ Future, Promise, Await } import scala.concurrent.ExecutionContext.Implicits.global object PingPong { final case class Ping(iterations: Int, replyTo: ActorRef[Pong]) case class Pong(iterations: Int, pingTo: ActorRef[Ping]) val pong = Behaviors.receive[Ping] { (ctx, msg) => msg.replyTo ! Pong(msg.iterations - 1, ctx.self) Behaviors.same } def ping(startTimePromise: Promise[Long], endTimePromise: Promise[Long], expectedIterations: Int) = Behaviors.receive[Pong] { (ctx, pong) => if (pong.iterations == 0) { endTimePromise.success(System.nanoTime()) Behaviors.stopped } else { if (expectedIterations == pong.iterations) { startTimePromise.success(System.nanoTime()) } pong.pingTo ! Ping(pong.iterations, ctx.self) Behaviors.same } } def mainActor( durationPromise: Promise[Long], numPairs: Int, numIterations: Int ): Behavior[akka.NotUsed] = Behaviors.setup { ctx => val (startTimePromises, startTimeFutures): (List[Promise[Long]], List[Future[Long]]) = (1 to numPairs).toList.map { _ => val startTimePromise = Promise[Long]() val startTimeFuture = startTimePromise.future (startTimePromise, startTimeFuture) }.unzip val (endTimePromises, endTimeFutures): (List[Promise[Long]], List[Future[Long]]) = (1 to numPairs).toList.map { _ => val endTimePromise = Promise[Long]() val endTimeFuture = endTimePromise.future (endTimePromise, endTimeFuture) }.unzip // val refs = (1 to numPairs).toList.map { id => val refs = startTimePromises.zip(endTimePromises).zipWithIndex.map { (promises, id) => val (sPromise, ePromise) = promises val pongRef = ctx.spawn(pong, "pong" + id) val pingRef = ctx.spawn(ping(sPromise, ePromise, numIterations), "ping" + id) ctx.watch(pingRef) (pingRef, pongRef) } refs.foreach { (pingRef, pongRef) => pingRef ! Pong(numIterations, pongRef) } val startTimes = Await.result(Future.sequence(startTimeFutures), Duration.Inf) val startTime = startTimes.min val endTimes = Await.result(Future.sequence(endTimeFutures), Duration.Inf) val endTime = endTimes.max durationPromise.success(endTime - startTime) val pingPongDuration = endTime - startTime var terminatedProcesses = 0 Behaviors.receiveSignal { case (_, Terminated(ref)) => terminatedProcesses = terminatedProcesses + 1 if (terminatedProcesses == numPairs) { Behaviors.stopped } else { Behaviors.same } Behaviors.stopped case (_, _) => Behaviors.empty } } def bench(params: (Int, Int)): Long = { val (numPairs, numIterations) = params val durationPromise = Promise[Long]() val durationFuture = durationPromise.future val system = ActorSystem( mainActor(durationPromise, numPairs, numIterations), "PingPongDemo") Await.result(system.whenTerminated, Duration.Inf) val duration = Await.result(durationFuture, Duration.Inf) duration } }
Example 6
Source File: ForkJoinCreation.scala From effpi with MIT License | 5 votes |
// Effpi - verified message-passing programs in Dotty // Copyright 2019 Alceste Scalas and Elias Benussi // Released under the MIT License: https://opensource.org/licenses/MIT package effpi.benchmarks.akka import akka.NotUsed import akka.actor.typed.scaladsl.{ Behaviors, MutableBehavior, ActorContext} import akka.actor.typed.{ ActorRef, ActorSystem, Behavior, DispatcherSelector, Terminated } import scala.concurrent.Future import scala.concurrent.duration._ import scala.concurrent.{ Future, Promise, Await } import scala.concurrent.ExecutionContext.Implicits.global object ForkJoinCreation { case class Message(msg: String) val simpleActor = Behaviors.receive[Message] { (ctx, msg) => Behaviors.stopped } def mainActor( durationPromise: Promise[Long], numActors: Int ): Behavior[akka.NotUsed] = Behaviors.setup { ctx => val startTime = System.nanoTime() val simpleActorRefs = (1 to numActors).toList.map { id => ctx.spawn(simpleActor, "simple" + id) } simpleActorRefs.foreach { simpleActorRef => simpleActorRef ! Message("Hello World!") } val endTime = System.nanoTime() durationPromise.success(endTime - startTime) Behaviors.stopped } def bench(params: Int): Long = { val durationPromise = Promise[Long]() val durationFuture = durationPromise.future val system = ActorSystem( mainActor(durationPromise, params), "ForkJoinCreationDemo") Await.result(system.whenTerminated, Duration.Inf) val duration = Await.result(durationFuture, Duration.Inf) duration } }
Example 7
Source File: ClusterListener.scala From akka-sample-cluster-docker-compose-scala with Apache License 2.0 | 5 votes |
package com.example import akka.actor.typed.Behavior import akka.actor.typed.scaladsl.Behaviors import akka.cluster.ClusterEvent import akka.cluster.ClusterEvent._ import akka.cluster.typed.Cluster import akka.cluster.typed.Subscribe object ClusterListener { def apply(): Behavior[ClusterEvent.ClusterDomainEvent] = Behaviors.setup { ctx => ctx.log.debug("starting up cluster listener...") Cluster(ctx.system).subscriptions ! Subscribe(ctx.self, classOf[ClusterEvent.ClusterDomainEvent]) Behaviors.receiveMessagePartial { case MemberUp(member) => ctx.log.debug("Member is Up: {}", member.address) Behaviors.same case UnreachableMember(member) => ctx.log.debug("Member detected as unreachable: {}", member) Behaviors.same case MemberRemoved(member, previousStatus) => ctx.log.debug("Member is Removed: {} after {}", member.address, previousStatus) Behaviors.same case LeaderChanged(member) => ctx.log.info("Leader changed: " + member) Behaviors.same case any: MemberEvent => ctx.log.info("Member Event: " + any.toString) Behaviors.same } } }
Example 8
Source File: GettingStarted.scala From lagom with Apache License 2.0 | 5 votes |
package docs.scaladsl.gettingstarted package helloservice { //#helloservice import akka.Done import akka.NotUsed import com.lightbend.lagom.scaladsl.api._ import play.api.libs.json._ trait HelloService extends Service { def hello(id: String): ServiceCall[NotUsed, String] def useGreeting(id: String): ServiceCall[GreetingMessage, Done] final override def descriptor = { import Service._ named("hello") .withCalls( pathCall("/api/hello/:id", hello _), pathCall("/api/hello/:id", useGreeting _) ) .withAutoAcl(true) } } case class GreetingMessage(message: String) object GreetingMessage { implicit val format: Format[GreetingMessage] = Json.format[GreetingMessage] } //#helloservice //#helloserviceimpl import akka.actor.typed.ActorRef import akka.actor.typed.Behavior import com.lightbend.lagom.scaladsl.api.ServiceCall import akka.cluster.sharding.typed.scaladsl.ClusterSharding import akka.cluster.sharding.typed.scaladsl.EntityRef import scala.concurrent.ExecutionContext import scala.concurrent.duration._ import akka.util.Timeout import com.lightbend.lagom.scaladsl.api.transport.BadRequest class HelloServiceImpl(clusterSharding: ClusterSharding)(implicit ec: ExecutionContext) extends HelloService { implicit val timeout = Timeout(5.seconds) override def hello(id: String): ServiceCall[NotUsed, String] = ServiceCall { _ => entityRef(id) .ask[Greeting](replyTo => Hello(id, replyTo)) .map(greeting => greeting.message) } override def useGreeting(id: String) = ServiceCall { request => entityRef(id) .ask[Confirmation](replyTo => UseGreetingMessage(request.message, replyTo)) .map { case Accepted => Done case _ => throw BadRequest("Can't upgrade the greeting message.") } } private def entityRef(id: String): EntityRef[HelloWorldCommand] = clusterSharding.entityRefFor(HelloWorldState.typeKey, id) } //#helloserviceimpl import com.lightbend.lagom.scaladsl.persistence.PersistentEntity.ReplyType import com.lightbend.lagom.scaladsl.persistence.PersistentEntity sealed trait HelloWorldCommand case class UseGreetingMessage(message: String, replyTo: ActorRef[Confirmation]) extends HelloWorldCommand case class Hello(name: String, replyTo: ActorRef[Greeting]) extends HelloWorldCommand final case class Greeting(message: String) sealed trait Confirmation sealed trait Accepted extends Confirmation case object Accepted extends Accepted case class Rejected(reason: String) extends Confirmation sealed trait HelloWorldEvent case class GreetingMessageChanged(message: String) extends HelloWorldEvent object HelloWorldState { import akka.cluster.sharding.typed.scaladsl.EntityTypeKey val typeKey = EntityTypeKey[HelloWorldCommand]("HelloWorldAggregate") } }
Example 9
Source File: EntityDb.scala From typebus with MIT License | 5 votes |
package io.surfkit.typebus.entity import io.surfkit.typebus.bus.Publisher import scala.concurrent.Future import scala.reflect.ClassTag import akka.actor.typed.Behavior import akka.cluster.sharding.typed.scaladsl.{EntityContext, EntityTypeKey} import io.surfkit.typebus.event.EntityCreated import io.surfkit.typebus.AvroByteStreams trait EntityDb[S] extends AvroByteStreams{ def producer: Publisher def typeKey: EntityTypeKey[_] def createEntity[M](behavior: String => Behavior[M])(implicit system: akka.actor.ActorSystem): EntityContext => Behavior[M] = { ctx: EntityContext => producer.publish(EntityCreated(typeKey.name, ctx.entityId)) behavior(ctx.entityId) } def getState(id: String): Future[S] def modifyState(id: String, state: S): Future[S] }
Example 10
Source File: ClusterStatusTrackerMain.scala From Pi-Akka-Cluster with Apache License 2.0 | 5 votes |
package akkapi.cluster import akka.NotUsed import akka.actor.typed.scaladsl.Behaviors import akka.actor.typed.{ActorSystem, Behavior, Terminated} import akka.management.scaladsl.AkkaManagement import akka.actor.typed.scaladsl.adapter.TypedActorSystemOps object Main { def apply(settings: Settings): Behavior[NotUsed] = Behaviors.setup { context => val ledStripDriver = context.spawn(LedStripDriver(settings), "led-strip-driver") val ledStripController = context.spawn(LedStripVisualiser(settings, ledStripDriver), "led-strip-controller") val clusterStatusTracker = context.spawn(ClusterStatusTracker(settings, None), "cluster-status-tracker") clusterStatusTracker ! ClusterStatusTracker.SubscribeVisualiser(ledStripController) Behaviors.receiveSignal { case (_, Terminated(_)) => Behaviors.stopped } } } object ClusterStatusTrackerMain { def main(args: Array[String]): Unit = { System.loadLibrary("rpi_ws281x") val settings = Settings() val config = settings.config val system = ActorSystem[NotUsed](Main(settings), settings.actorSystemName, config) // Start Akka HTTP Management extension AkkaManagement(system.toClassic).start() } }
Example 11
Source File: ConfigurablePersistentActor.scala From akka-persistence-cassandra with Apache License 2.0 | 5 votes |
package akka.persistence.cassandra.example import akka.actor.typed.scaladsl.Behaviors import akka.actor.typed.{ ActorRef, ActorSystem, Behavior } import akka.cluster.sharding.typed.ShardingEnvelope import akka.cluster.sharding.typed.scaladsl.{ ClusterSharding, Entity, EntityTypeKey } import akka.persistence.typed.PersistenceId import akka.persistence.typed.scaladsl.{ Effect, EventSourcedBehavior } object ConfigurablePersistentActor { case class Settings(nrTags: Int) val Key: EntityTypeKey[Event] = EntityTypeKey[Event]("configurable") def init(settings: Settings, system: ActorSystem[_]): ActorRef[ShardingEnvelope[Event]] = { ClusterSharding(system).init(Entity(Key)(ctx => apply(settings, ctx.entityId)).withRole("write")) } final case class Event(timeCreated: Long = System.currentTimeMillis()) extends CborSerializable final case class State(eventsProcessed: Long) extends CborSerializable def apply(settings: Settings, persistenceId: String): Behavior[Event] = Behaviors.setup { ctx => EventSourcedBehavior[Event, Event, State]( persistenceId = PersistenceId.ofUniqueId(persistenceId), State(0), (_, event) => { ctx.log.info("persisting event {}", event) Effect.persist(event) }, (state, _) => state.copy(eventsProcessed = state.eventsProcessed + 1)).withTagger(event => Set("tag-" + math.abs(event.hashCode() % settings.nrTags))) } }
Example 12
Source File: ClientEntity.scala From Pi-Akka-Cluster with Apache License 2.0 | 5 votes |
package com.lightbend.akka_oled import akka.actor.typed.scaladsl.Behaviors import akka.actor.typed.{ActorRef, Behavior} import akka.cluster.sharding.typed.scaladsl.EntityTypeKey import akka.persistence.typed.PersistenceId import akka.persistence.typed.scaladsl.{Effect, EventSourcedBehavior} import com.lightbend.akka_oled.OledShardingVisualizer.Notification object ClientEntity { sealed trait Command case class PostPoints(name: String, amount: Int)(val replyTo: ActorRef[String]) extends Command case class Get(name: String)(val replyTo: ActorRef[Int]) extends Command final case class PointsAdded(name: String, points: Int) val TypeKey: EntityTypeKey[Command] = EntityTypeKey[Command]("ClientEntity") final case class ClientPoints(name: String, points: Int, visualizer: ActorRef[Notification]) { def add(delta: Int) = copy(points = points + delta) } private val commandHandler: (ClientPoints, Command) => Effect[PointsAdded, ClientPoints] = { (state, cmd) => cmd match { case pp@PostPoints(name, amount) => Effect.persist(PointsAdded(name, amount)).thenRun(s => { state.visualizer ! Notification(s.name, s.points) pp.replyTo ! "Ok\n" }) case g@Get(_) => g.replyTo ! state.points state.visualizer ! Notification(state.name, state.points) Effect.none } } private val eventHandler: (ClientPoints, PointsAdded) => ClientPoints = { (state, evt) => state.add(evt.points) } def apply(entityId: String, persistenceId: PersistenceId, visualizer: ActorRef[Notification]): Behavior[ClientEntity.Command] = Behaviors.setup { _ => EventSourcedBehavior(persistenceId, ClientPoints(entityId, 0, visualizer), commandHandler, eventHandler) } }
Example 13
Source File: OledShardingVisualizer.scala From Pi-Akka-Cluster with Apache License 2.0 | 5 votes |
package com.lightbend.akka_oled import akka.actor.typed.scaladsl.Behaviors import akka.actor.typed.{ActorRef, Behavior} import akka.cluster.sharding.ShardRegion.ShardState import akkapi.cluster.OledDriver import akkapi.cluster.OledDriver.UpdateView import com.lightbend.akka_oled.OledShardingVisualizer.{Notification, ShardRegionState} object OledShardingVisualizer { sealed trait Command case class ShardRegionState(shards: Set[ShardState]) extends Command case class Notification(name: String, total: Int) extends Command def apply(screenIndex: Int, oledDriver: ActorRef[OledDriver.Command]): Behavior[OledShardingVisualizer.Command] = Behaviors.setup { context => Behaviors.withTimers[Command] { timer => new OledShardingVisualizer(screenIndex, oledDriver).running( clients = Map.empty[String, Int], shardToClientName = Map.empty[String, Set[String]] ) } } } class OledShardingVisualizer private(screenIndex: Int, oledDriver: ActorRef[OledDriver.Command]) { def running(clients: Map[String, Int], shardToClientName: Map[String, Set[String]] ): Behavior[OledShardingVisualizer.Command] = Behaviors .receiveMessage[OledShardingVisualizer.Command] { case Notification(name, total) => val newClients = clients + (name -> total) oledDriver ! UpdateView(screenIndex, renderState(newClients, shardToClientName)) running(newClients, shardToClientName) case ShardRegionState(shards: Set[ShardState]) => val entityIds: Set[String] = shards.flatMap(_.entityIds) val newShardToClientName = shards.foldLeft(Map.empty[String, Set[String]]) { case (map, value) => map + (value.shardId.toString -> value.entityIds.map(_.toString)) } val withNewClients: Map[String, Int] = entityIds.foldLeft(clients)((map, a) => if (clients.get(a).isEmpty) map + (a -> 0) else map) //remove old shards val updatedClients = withNewClients.filter { case (k, _) => entityIds.contains(k) } oledDriver ! UpdateView(screenIndex, renderState(updatedClients, newShardToClientName)) running(updatedClients, newShardToClientName) } private def renderState(clients: Map[String, Int], shardToClientName: Map[String, Set[String]]): String = { if (clients.nonEmpty) shardToClientName.flatMap[String] { case (key, names) => names.map { name => "Shard#" + key + "->" + name + ": " + clients.getOrElse(name, 0) } }.mkString("\n") else "No data" } }
Example 14
Source File: Main.scala From Pi-Akka-Cluster with Apache License 2.0 | 5 votes |
package com.lightbend.akka_oled import akka.NotUsed import akka.actor.typed.scaladsl.Behaviors import akka.actor.typed.scaladsl.adapter.TypedActorSystemOps import akka.actor.typed.{ActorSystem, Behavior, Terminated} import akka.cluster.sharding.typed.scaladsl.{ClusterSharding, Entity} import akka.http.scaladsl.Http import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport import akka.management.scaladsl.AkkaManagement import akka.persistence.typed.PersistenceId import akka.stream.Materializer import akkapi.cluster.{ClusterStatusTracker, OledClusterVisualizer, OledDriver, Settings} import spray.json._ import scala.concurrent.ExecutionContextExecutor object Main extends SprayJsonSupport with DefaultJsonProtocol { case class AddPoints(points: Int) implicit val transactionFormat = jsonFormat1(AddPoints) def apply(settings: Settings): Behavior[NotUsed] = Behaviors.setup { ctx => implicit val system = ctx.system implicit val untypedSystem: akka.actor.ActorSystem = ctx.system.toClassic implicit val ec: ExecutionContextExecutor = ctx.system.executionContext val oledDriver = ctx.spawn(OledDriver(settings), "oled-driver") oledDriver ! OledDriver.RegisterView("Cluster State", 0) oledDriver ! OledDriver.RegisterView("Sharding State", 1) val clusterView = ctx.spawn(OledClusterVisualizer(0, settings, oledDriver), "oled-cluster-view") val clusterStatusTracker = ctx.spawn(ClusterStatusTracker(settings, None), "cluster-status-tracker") clusterStatusTracker ! ClusterStatusTracker.SubscribeVisualiser(clusterView) val shardVisualizer = ctx.spawn(OledShardingVisualizer(1, oledDriver), "oled-sharding-view") val sharding = ClusterSharding(ctx.system) sharding.init(Entity(typeKey = ClientEntity.TypeKey) { entityContext => ClientEntity(entityContext.entityId, PersistenceId(entityContext.entityTypeKey.name, entityContext.entityId), shardVisualizer) }) val tracker = ctx.spawn(ShardStateTracker(shardVisualizer), "oled-sharding-tracker") ctx.spawn(ShardStateScheduler(sharding.shardState, tracker), "oled-sharding-scheduler") val routes = new Routes(sharding) //materializer Materializer.createMaterializer(ctx.system.toClassic) implicit val mat: Materializer = Materializer.createMaterializer(ctx.system.toClassic) Http()(ctx.system.toClassic).bindAndHandle(routes.route, settings.config.getString("cluster-node-configuration.external-ip"), 8080) Behaviors.receiveSignal { case (_, Terminated(_)) => Behaviors.stopped } } } object DisplayClusterShardingMain { def main(args: Array[String]): Unit = { val settings = Settings() val system = ActorSystem[NotUsed](Main(settings), "akka-oled", settings.config) // Start Akka HTTP Management extension AkkaManagement(system).start() } }
Example 15
Source File: DisplayClusterStatusMain.scala From Pi-Akka-Cluster with Apache License 2.0 | 5 votes |
package com.lightbend.akka_oled import akka.NotUsed import akka.actor.typed.scaladsl.Behaviors import akka.actor.typed.{ActorSystem, Behavior, Terminated} import akka.management.scaladsl.AkkaManagement import akkapi.cluster.{ClusterStatusTracker, OledClusterVisualizer, OledDriver, Settings} object Main { def apply(settings: Settings): Behavior[NotUsed] = Behaviors.setup { context => val oledDriver = context.spawn(OledDriver(settings), "oled-driver") val clusterView = context.spawn(OledClusterVisualizer(0, settings, oledDriver), "oled-cluster-view") oledDriver ! OledDriver.RegisterView("Cluster State", 0) val clusterStatusTracker = context.spawn(ClusterStatusTracker(settings, None), "cluster-status-tracker") clusterStatusTracker ! ClusterStatusTracker.SubscribeVisualiser(clusterView) Behaviors.receiveSignal { case (_, Terminated(_)) => Behaviors.stopped } } } object DisplayClusterStatusMain { def main(args: Array[String]): Unit = { val settings = Settings() val config = settings.config val system = ActorSystem[NotUsed](Main(settings), "akka-oled", config) // Start Akka HTTP Management extension AkkaManagement(system).start() } }
Example 16
Source File: ClusterStatusTrackerMain.scala From Pi-Akka-Cluster with Apache License 2.0 | 5 votes |
package akkapi.cluster import akka.NotUsed import akka.actor.typed.scaladsl.adapter.TypedActorSystemOps import akka.actor.typed.scaladsl.{ActorContext, Behaviors, Routers} import akka.actor.typed.{ActorSystem, Behavior, Terminated} import akka.cluster.typed.{ClusterSingleton, SingletonActor} import akka.management.scaladsl.AkkaManagement import akkapi.cluster.sudoku.{SudokuSolverSettings, SudokuSolver, SudokuProblemSender} object Main { def apply(settings: Settings): Behavior[NotUsed] = Behaviors.setup { context => val sudokuSolverSettings = SudokuSolverSettings("sudokusolver.conf") // Start CLusterStatusTracker & LedStripVisualiser val ledStripDriver = context.spawn(LedStripDriver(settings), "led-strip-driver") val ledStripController = context.spawn(LedStripVisualiser(settings, ledStripDriver), "led-strip-controller") val clusterStatusTracker = context.spawn( ClusterStatusTracker( settings, Some(contextToClusterSingleton(settings)) ), "cluster-status-tracker" ) clusterStatusTracker ! ClusterStatusTracker.SubscribeVisualiser(ledStripController) // Start SodukuSolver: we'll run one instance/cluster node context.spawn(SudokuSolver(ledStripDriver, sudokuSolverSettings), s"sudoku-solver") // We'll use a [cluster-aware] group router val sudokuSolverGroup = context.spawn(Routers.group(SudokuSolver.Key).withRoundRobinRouting(), "sudoku-solvers") // And run one instance if the Sudoku problem sender in the cluster ClusterSingleton(context.system).init(SingletonActor(SudokuProblemSender(sudokuSolverGroup, sudokuSolverSettings), "sudoku-problem-sender")) Behaviors.receiveSignal { case (_, Terminated(_)) => Behaviors.stopped } } private def contextToClusterSingleton(settings: Settings): ActorContextToSingletonBehavior = (context: ActorContext[ClusterStatusTracker.ClusterEvent]) => PiClusterSingleton(settings, context.self) type ActorContextToSingletonBehavior = ActorContext[ClusterStatusTracker.ClusterEvent] => Behavior[PiClusterSingleton.Command] } object ClusterStatusTrackerMain { def main(args: Array[String]): Unit = { System.loadLibrary("rpi_ws281x") val settings = Settings() val config = settings.config val system = ActorSystem[NotUsed](Main(settings), settings.actorSystemName, config) val classicSystem = system.toClassic // Start Akka HTTP Management extension AkkaManagement(classicSystem).start() } }
Example 17
Source File: SudokuProblemSender.scala From Pi-Akka-Cluster with Apache License 2.0 | 5 votes |
package akkapi.cluster.sudoku import java.io.File import akka.actor.typed.scaladsl.{ActorContext, Behaviors, TimerScheduler} import akka.actor.typed.{ActorRef, Behavior} object SudokuProblemSender { sealed trait Command case object SendNewSudoku extends Command // Wrapped responses private final case class SolutionWrapper(result: SudokuSolver.Response) extends Command private val rowUpdates: Seq[SudokuDetailProcessor.RowUpdate] = SudokuIO.readSudokuFromFile(new File("sudokus/001.sudoku")) .map { case (rowIndex, update) => SudokuDetailProcessor.RowUpdate(rowIndex, update) } def apply(sudokuSolver: ActorRef[SudokuSolver.Command], sudokuSolverSettings: SudokuSolverSettings): Behavior[Command] = Behaviors.setup { context => Behaviors.withTimers { timers => new SudokuProblemSender(sudokuSolver, context, timers, sudokuSolverSettings).sending() } } } class SudokuProblemSender private (sudokuSolver: ActorRef[SudokuSolver.Command], context: ActorContext[SudokuProblemSender.Command], timers: TimerScheduler[SudokuProblemSender.Command], sudokuSolverSettings: SudokuSolverSettings) { import SudokuProblemSender._ private val solutionWrapper: ActorRef[SudokuSolver.Response] = context.messageAdapter(response => SolutionWrapper(response)) private val initialSudokuField = rowUpdates.toSudokuField private val rowUpdatesSeq = LazyList.continually( Seq( initialSudokuField, initialSudokuField.flipVertically, initialSudokuField.flipHorizontally, initialSudokuField.flipHorizontally.flipVertically, initialSudokuField.flipVertically.flipHorizontally, initialSudokuField.columnSwap(0,1), initialSudokuField.rowSwap(4,5).rowSwap(0, 2), initialSudokuField.randomSwapAround, initialSudokuField.randomSwapAround, initialSudokuField.rotateCW, initialSudokuField.rotateCCW, initialSudokuField.rotateCW.rotateCW, initialSudokuField.transpose, initialSudokuField.randomSwapAround, initialSudokuField.rotateCW.transpose, initialSudokuField.randomSwapAround, initialSudokuField.rotateCCW.transpose, initialSudokuField.randomSwapAround, initialSudokuField.randomSwapAround, initialSudokuField.flipVertically.transpose, initialSudokuField.flipVertically.rotateCW, initialSudokuField.columnSwap(4,5).columnSwap(0, 2).rowSwap(3,4), initialSudokuField.rotateCW.rotateCW.transpose ).map(_.toRowUpdates)).flatten.iterator private val problemSendInterval = sudokuSolverSettings.ProblemSender.SendInterval timers.startTimerAtFixedRate(SendNewSudoku, problemSendInterval) // on a 5 node RPi 4 based cluster in steady state, this can be lowered to about 6ms def sending(): Behavior[Command] = Behaviors.receiveMessagePartial { case SendNewSudoku => context.log.debug("sending new sudoku problem") sudokuSolver ! SudokuSolver.InitialRowUpdates(rowUpdatesSeq.next, solutionWrapper) Behaviors.same case SolutionWrapper(solution: SudokuSolver.SudokuSolution) => context.log.info(s"${SudokuIO.sudokuPrinter(solution)}") Behaviors.same } }
Example 18
Source File: SudokuProgressTracker.scala From Pi-Akka-Cluster with Apache License 2.0 | 5 votes |
package akkapi.cluster.sudoku import akka.actor.typed.scaladsl.{ActorContext, Behaviors} import akka.actor.typed.{ActorRef, Behavior} object SudokuProgressTracker { sealed trait Command final case class NewUpdatesInFlight(count: Int) extends Command final case class SudokuDetailState(index: Int, state: ReductionSet) extends Command // My responses sealed trait Response final case class Result(sudoku: Sudoku) extends Response def apply(rowDetailProcessors: Map[Int, ActorRef[SudokuDetailProcessor.Command]], sudokuSolver: ActorRef[Response]): Behavior[Command] = Behaviors.setup { context => new SudokuProgressTracker(rowDetailProcessors, context, sudokuSolver).trackProgress(updatesInFlight = 0) } } class SudokuProgressTracker private (rowDetailProcessors: Map[Int, ActorRef[SudokuDetailProcessor.Command]], context: ActorContext[SudokuProgressTracker.Command], sudokuSolver: ActorRef[SudokuProgressTracker.Response]) { import SudokuProgressTracker._ def trackProgress(updatesInFlight: Int): Behavior[Command] = Behaviors.receiveMessagePartial { case NewUpdatesInFlight(updateCount) if updatesInFlight - 1 == 0 => rowDetailProcessors.foreach { case (_, processor) => processor ! SudokuDetailProcessor.GetSudokuDetailState(context.self) } collectEndState() case NewUpdatesInFlight(updateCount) => trackProgress(updatesInFlight + updateCount) } def collectEndState(remainingRows: Int = 9, endState: Vector[SudokuDetailState] = Vector.empty[SudokuDetailState]): Behavior[Command] = Behaviors.receiveMessagePartial { case detail @ SudokuDetailState(index, state) if remainingRows == 1 => sudokuSolver ! Result((detail +: endState).sortBy { case SudokuDetailState(idx, _) => idx }.map { case SudokuDetailState(_, state) => state}) trackProgress(updatesInFlight = 0) case detail @ SudokuDetailState(index, state) => collectEndState(remainingRows = remainingRows - 1, detail +: endState) } }
Example 19
Source File: PiClusterSingleton.scala From Pi-Akka-Cluster with Apache License 2.0 | 5 votes |
package akkapi.cluster import akka.actor.typed.scaladsl.{ActorContext, Behaviors} import akka.actor.typed.{ActorRef, Behavior, PostStop} import akkapi.cluster.{ClusterStatusTracker, Settings} object PiClusterSingleton { sealed trait Command final case object Ping extends Command def apply(settings: Settings, clusterStatusTracker: ActorRef[ClusterStatusTracker.ClusterEvent]): Behavior[Command] = { Behaviors.setup { context => new PiClusterSingleton(context, settings, clusterStatusTracker).run() } } } class PiClusterSingleton private (context: ActorContext[PiClusterSingleton.Command], settings: Settings, clusterStatusTracker: ActorRef[ClusterStatusTracker.ClusterEvent]) { import PiClusterSingleton._ // Cluster singleton has been started on this node clusterStatusTracker ! ClusterStatusTracker.PiClusterSingletonOnNode def run(): Behavior[Command] = Behaviors.receiveMessage[Command] { case Ping => context.log.info(s"PiClusterSingleton was pinged") Behaviors.same }.receiveSignal { case (_, signal) if signal == PostStop => clusterStatusTracker ! ClusterStatusTracker.PiClusterSingletonNotOnNode Behaviors.same } }
Example 20
Source File: Main.scala From streamee with Apache License 2.0 | 5 votes |
package io.moia.streamee.demo import akka.actor.{ ActorSystem => ClassicSystem } import akka.actor.CoordinatedShutdown.Reason import akka.actor.typed.{ Behavior, Scheduler } import akka.actor.typed.scaladsl.{ ActorContext, Behaviors } import akka.actor.typed.scaladsl.adapter.{ ClassicActorSystemOps, TypedActorSystemOps } import akka.cluster.typed.{ Cluster, ClusterSingleton, SelfUp, SingletonActor, Subscribe, Unsubscribe } import akka.management.cluster.bootstrap.ClusterBootstrap import akka.management.scaladsl.AkkaManagement import io.moia.streamee.FrontProcessor import org.apache.logging.log4j.core.async.AsyncLoggerContextSelector import org.slf4j.LoggerFactory import pureconfig.generic.auto.exportReader import pureconfig.ConfigSource import scala.concurrent.ExecutionContext import scala.concurrent.duration.FiniteDuration object Main { final case class Config( api: Api.Config, textShufflerProcessorTimeout: FiniteDuration, textShuffler: TextShuffler.Config ) final object TopLevelActorTerminated extends Reason private val logger = LoggerFactory.getLogger(getClass) def main(args: Array[String]): Unit = { // Always use async logging! sys.props += "log4j2.contextSelector" -> classOf[AsyncLoggerContextSelector].getName // Must happen before creating the actor system! val config = ConfigSource.default.at("streamee-demo").loadOrThrow[Config] // Always start with a classic system! val system = ClassicSystem("streamee-demo") system.spawn(Main(config), "main") // Cluster bootstrap AkkaManagement(system).start() ClusterBootstrap(system).start() } def apply(config: Config): Behavior[SelfUp] = Behaviors.setup { context => if (logger.isInfoEnabled) logger.info(s"${context.system.name} started and ready to join cluster") Cluster(context.system).subscriptions ! Subscribe(context.self, classOf[SelfUp]) Behaviors.receive { (context, _) => if (logger.isInfoEnabled) logger.info(s"${context.system.name} joined cluster and is up") Cluster(context.system).subscriptions ! Unsubscribe(context.self) initialize(config)(context) Behaviors.empty } } private def initialize(config: Config)(implicit context: ActorContext[_]) = { import config._ implicit val classicSystem: ClassicSystem = context.system.toClassic implicit val ec: ExecutionContext = context.executionContext implicit val scheduler: Scheduler = context.system.scheduler val wordShufflerRunner = ClusterSingleton(context.system).init( SingletonActor(WordShufflerRunner(), "word-shuffler") .withStopMessage(WordShufflerRunner.Shutdown) ) val textShufflerProcessor = FrontProcessor( TextShuffler(config.textShuffler, wordShufflerRunner), textShufflerProcessorTimeout, "text-shuffler" ) Api(config.api, textShufflerProcessor) } }
Example 21
Source File: Api.scala From whirlwind-tour-akka-typed with Apache License 2.0 | 5 votes |
package de.heikoseeberger.wtat import akka.actor.{ ActorSystem, Scheduler } import akka.http.scaladsl.Http import akka.http.scaladsl.Http.ServerBinding import akka.http.scaladsl.model.StatusCodes.{ Conflict, Created, NoContent, NotFound } import akka.http.scaladsl.server.{ Directives, Route } import akka.stream.Materializer import akka.actor.typed.scaladsl.Actor import akka.actor.typed.scaladsl.AskPattern.Askable import akka.actor.typed.{ ActorRef, Behavior } import akka.util.Timeout import de.heikoseeberger.akkahttpcirce.ErrorAccumulatingCirceSupport import java.net.InetSocketAddress import org.apache.logging.log4j.scala.Logging import scala.concurrent.duration.FiniteDuration import scala.util.{ Failure, Success } object Api extends Logging { sealed trait Command private final case object HandleBindFailure extends Command private final case class HandleBound(address: InetSocketAddress) extends Command final val Name = "api" def apply(address: String, port: Int, userRepository: ActorRef[UserRepository.Command], userView: ActorRef[UserView.Command], askTimeout: FiniteDuration)(implicit mat: Materializer): Behavior[Command] = Actor.deferred { context => import akka.actor.typed.scaladsl.adapter._ import context.executionContext implicit val s: ActorSystem = context.system.toUntyped val self = context.self Http() .bindAndHandle(route(userRepository, userView)(askTimeout, context.system.scheduler), address, port) .onComplete { case Failure(_) => self ! HandleBindFailure case Success(ServerBinding(address)) => self ! HandleBound(address) } Actor.immutable { case (_, HandleBindFailure) => logger.error(s"Stopping, because cannot bind to $address:$port!") Actor.stopped case (_, HandleBound(address)) => logger.info(s"Bound to $address") Actor.ignore } } def route( userRepository: ActorRef[UserRepository.Command], userView: ActorRef[UserView.Command] )(implicit askTimeout: Timeout, scheduler: Scheduler): Route = { import Directives._ import ErrorAccumulatingCirceSupport._ import io.circe.generic.auto._ import io.circe.refined._ pathEndOrSingleSlash { get { complete { import UserView._ (userView ? GetUsers).mapTo[Users] } } ~ post { entity(as[User]) { user => import UserRepository._ onSuccess(userRepository ? addUser(user)) { case UsernameTaken(_) => complete(Conflict) case UserAdded(_) => complete(Created) } } } } ~ path(Segment) { username => delete { import UserRepository._ onSuccess(userRepository ? removeUser(username)) { case UsernameUnknown(_) => complete(NotFound) case UserRemoved(_) => complete(NoContent) } } } } }
Example 22
Source File: UserProjection.scala From whirlwind-tour-akka-typed with Apache License 2.0 | 5 votes |
package de.heikoseeberger.wtat import akka.actor.Scheduler import akka.actor.typed.{ ActorRef, Behavior } import akka.actor.typed.scaladsl.Actor import akka.actor.typed.scaladsl.AskPattern.Askable import akka.cluster.Cluster import akka.cluster.ddata.{ ORSet, ORSetKey } import akka.cluster.ddata.Replicator.WriteLocal import akka.cluster.ddata.typed.scaladsl.{ DistributedData, Replicator } import akka.persistence.query.EventEnvelope import akka.persistence.query.scaladsl.EventsByPersistenceIdQuery import akka.stream.Materializer import akka.stream.scaladsl.Sink import akka.util.Timeout import cats.instances.string._ import cats.syntax.eq._ import org.apache.logging.log4j.scala.Logging import scala.concurrent.duration.FiniteDuration object UserProjection extends Logging { import akka.actor.typed.scaladsl.adapter._ sealed trait Command final case object Stop extends Command private final case object HandleEventStreamComplete extends Command abstract class EventStreamCompleteException extends IllegalStateException("Event stream completed unexpectedly!") private final case object EventStreamCompleteException extends EventStreamCompleteException final val Name = "user-projection" final val usersKey: ORSetKey[User] = ORSetKey("users") def apply(readJournal: EventsByPersistenceIdQuery, userView: ActorRef[UserView.Command], askTimeout: FiniteDuration)(implicit mat: Materializer): Behavior[Command] = Actor.deferred { context => implicit val c: Cluster = Cluster(context.system.toUntyped) implicit val s: Scheduler = context.system.scheduler implicit val t: Timeout = askTimeout val replicator = DistributedData(context.system).replicator val self = context.self readJournal .eventsByPersistenceId(UserRepository.Name, 0, Long.MaxValue) .collect { case EventEnvelope(_, _, _, event: UserRepository.Event) => event } .mapAsync(1) { case UserRepository.UserAdded(user) => replicator ? Replicator.Update(usersKey, ORSet.empty[User], WriteLocal)(_ + user) case UserRepository.UserRemoved(username) => replicator ? Replicator.Update(usersKey, ORSet.empty[User], WriteLocal) { users => users.elements.find(_.username.value === username).fold(users)(users - _) } } .runWith(Sink.onComplete(_ => self ! HandleEventStreamComplete)) logger.debug("Running event stream") Actor.immutable { case (_, Stop) => Actor.stopped case (_, HandleEventStreamComplete) => throw EventStreamCompleteException } } }
Example 23
Source File: UserRepository.scala From whirlwind-tour-akka-typed with Apache License 2.0 | 5 votes |
package de.heikoseeberger.wtat import akka.actor.typed.{ ActorRef, Behavior } import akka.persistence.typed.scaladsl.PersistentActor import akka.persistence.typed.scaladsl.PersistentActor.{ CommandHandler, Effect } import eu.timepit.refined.api.Refined import java.io.{ Serializable => JavaSerializable } import org.apache.logging.log4j.scala.Logging object UserRepository extends Logging { sealed trait Serializable extends JavaSerializable sealed trait Command sealed trait Event final case class AddUser(user: User, replyTo: ActorRef[AddUserReply]) extends Command with Serializable sealed trait AddUserReply final case class UsernameTaken(username: String) extends AddUserReply with Serializable final case class UserAdded(user: User) extends AddUserReply with Event with Serializable final case class RemoveUser(username: String, replyTo: ActorRef[RemoveUserReply]) extends Command with Serializable sealed trait RemoveUserReply final case class UsernameUnknown(username: String) extends RemoveUserReply with Serializable final case class UserRemoved(username: String) extends RemoveUserReply with Event with Serializable final case object Stop extends Command final case class State(usernames: Set[String] = Set.empty) final val Name = "user-repository" def apply(): Behavior[Command] = PersistentActor.immutable(Name, State(), commandHandler, eventHandler) def addUser(user: User)(replyTo: ActorRef[AddUserReply]): AddUser = AddUser(user, replyTo) def removeUser(username: String)(replyTo: ActorRef[RemoveUserReply]): RemoveUser = RemoveUser(username, replyTo) private def commandHandler = CommandHandler[Command, Event, State] { case (_, State(usernames), AddUser(user @ User(Refined(username), _), replyTo)) => if (usernames.contains(username)) { logger.info(s"Username $username taken") replyTo ! UsernameTaken(username) Effect.none } else { val userAdded = UserAdded(user) Effect .persist(userAdded) .andThen { _ => logger.info(s"User with username $username added") replyTo ! userAdded } } case (_, State(usernames), RemoveUser(username, replyTo)) => if (!usernames.contains(username)) { logger.info(s"Username $username unknown") replyTo ! UsernameUnknown(username) Effect.none } else { val userRemoved = UserRemoved(username) Effect .persist(userRemoved) .andThen { _ => logger.info(s"User with username $username removed") replyTo ! userRemoved } } case (_, _, Stop) => Effect.stop } private def eventHandler(state: State, event: Event) = event match { case UserAdded(user) => state.copy(state.usernames + user.username.value) case UserRemoved(username) => state.copy(state.usernames - username) } }
Example 24
Source File: UserView.scala From whirlwind-tour-akka-typed with Apache License 2.0 | 5 votes |
package de.heikoseeberger.wtat import akka.actor.typed.scaladsl.Actor import akka.actor.typed.{ ActorRef, Behavior } import akka.cluster.ddata.ORSet import akka.cluster.ddata.typed.scaladsl.{ DistributedData, Replicator } import org.apache.logging.log4j.scala.Logging object UserView extends Logging { sealed trait Command final case class GetUsers(replyTo: ActorRef[Users]) extends Command final case class Users(users: Set[User]) private final case class UsersChanged(users: Set[User]) extends Command final val Name = "user-view" def apply(users: Set[User] = Set.empty): Behavior[Command] = Actor.deferred { context => val changedAdapter = context.spawnAdapter { (changed: Replicator.Changed[ORSet[User]]) => UsersChanged(changed.dataValue.elements) } val replicator = DistributedData(context.system).replicator replicator ! Replicator.Subscribe(UserProjection.usersKey, changedAdapter) Actor.immutable { case (_, GetUsers(replyTo)) => replyTo ! Users(users) Actor.same case (_, UsersChanged(users)) => UserView(users) } } }
Example 25
Source File: ModelServerManagerBehavior.scala From model-serving-tutorial with Apache License 2.0 | 5 votes |
package com.lightbend.modelserving.akka import akka.actor.typed.scaladsl.{AbstractBehavior, ActorContext, Behaviors} import akka.actor.typed.{ActorRef, Behavior} import com.lightbend.modelserving.model.ModelToServeStats class ModelServerManagerBehavior(context: ActorContext[ModelServerManagerActor]) extends AbstractBehavior[ModelServerManagerActor] { println("Creating Model Serving Manager") private def getModelServer(dataType: String): ActorRef[ModelServerActor] = { context.child(dataType) match { case Some(actorRef) => actorRef.asInstanceOf[ActorRef[ModelServerActor]] case _ => context.spawn(Behaviors.setup[ModelServerActor]( context => new ModelServerBehavior(context, dataType)), dataType) } } private def getInstances : GetModelsResult = GetModelsResult(context.children.map(_.path.name).toSeq) override def onMessage(msg: ModelServerManagerActor): Behavior[ModelServerManagerActor] = { msg match { case updateModel : UpdateModel => getModelServer(updateModel.model.dataType) tell updateModel case scoreData : ScoreData => getModelServer(scoreData.record.getType) tell scoreData case getState : GetState => // Used for state queries context.child(getState.dataType) match{ case Some(server) => server.asInstanceOf[ActorRef[ModelServerActor]] tell getState case _ => getState.reply ! ModelToServeStats() } case getModels : GetModels => // Get list of models getModels.reply ! getInstances } this } }
Example 26
Source File: ModelServerBehavior.scala From model-serving-tutorial with Apache License 2.0 | 5 votes |
package com.lightbend.modelserving.akka import akka.Done import akka.actor.typed.Behavior import akka.actor.typed.scaladsl.{AbstractBehavior, ActorContext} import com.lightbend.model.winerecord.WineRecord import com.lightbend.modelserving.model.{Model, ModelToServe, ModelToServeStats, ServingResult} class ModelServerBehavior(context: ActorContext[ModelServerActor], dataType : String) extends AbstractBehavior[ModelServerActor] { println(s"Creating a new Model Server for data type $dataType") private var currentModel: Option[Model[WineRecord, Double]] = None var currentState: Option[ModelToServeStats] = None override def onMessage(msg: ModelServerActor): Behavior[ModelServerActor] = { msg match { case update : UpdateModel => // Update Model // Update model println(s"Updated model: ${update.model}") ModelToServe.toModel[WineRecord, Double](update.model) match { case Some(m) => // Successfully got a new model // close current model first currentModel.foreach(_.cleanup()) // Update model and state currentModel = Some(m) currentState = Some(ModelToServeStats(update.model)) case _ => // Failed converting println(s"Failed to convert model: ${update.model}") } update.reply ! Done case scoreData : ScoreData => // Serve data // Actually process data val result = currentModel match { case Some(model) => { val start = System.currentTimeMillis() // Actually serve val result = model.score(scoreData.record.getRecord) val duration = System.currentTimeMillis() - start // Update state currentState = Some(currentState.get.incrementUsage(duration)) // result Some(ServingResult(currentState.get.name, scoreData.record.getType, scoreData.record.getRecord.asInstanceOf[WineRecord].ts, result.asInstanceOf[Double])) } case _ => None } scoreData.reply ! result case getState : GetState => // State query getState.reply ! currentState.getOrElse(ModelToServeStats()) } this } }
Example 27
Source File: WsHeart.scala From AckCord with MIT License | 5 votes |
package ackcord.voice import scala.concurrent.duration._ import akka.actor.typed.scaladsl.{ActorContext, Behaviors, TimerScheduler} import akka.actor.typed.{ActorRef, Behavior} object WsHeart { def apply(parent: ActorRef[VoiceWsHandler.Command]): Behavior[Command] = Behaviors.setup { ctx => Behaviors.withTimers(timers => runningHeart(ctx, timers, parent, None, receivedAck = true)) } def runningHeart( context: ActorContext[Command], timers: TimerScheduler[Command], parent: ActorRef[VoiceWsHandler.Command], previousNonce: Option[Int], receivedAck: Boolean ): Behavior[Command] = Behaviors.receiveMessage { case StartBeating(interval, nonce) => context.log.debug(s"Starting to beat with initial nonce $nonce") timers.startTimerAtFixedRate("heartbeatTimerKey", Beat, interval.millis) runningHeart(context, timers, parent, Some(nonce), receivedAck = true) case StopBeating => timers.cancel("heartbeatTimerKey") runningHeart(context, timers, parent, None, receivedAck = true) case BeatAck(nonce) => val log = context.log log.debug(s"Received HeartbeatACK with nonce $nonce") if (previousNonce.contains(nonce)) runningHeart(context, timers, parent, None, receivedAck = true) else { log.warn("Did not receive correct nonce in HeartbeatACK. Restarting.") parent ! VoiceWsHandler.Restart(fresh = false, 500.millis) Behaviors.same } case Beat => val log = context.log if (receivedAck) { val nonce = System.currentTimeMillis().toInt parent ! VoiceWsHandler.SendHeartbeat(nonce) log.debug(s"Sent Heartbeat with nonce $nonce") runningHeart(context, timers, parent, previousNonce = Some(nonce), receivedAck = false) } else { log.warn("Did not receive HeartbeatACK between heartbeats. Restarting.") parent ! VoiceWsHandler.Restart(fresh = false, 0.millis) Behaviors.same } } sealed trait Command case class StartBeating(interval: Double, nonce: Int) extends Command case object StopBeating extends Command case class BeatAck(nonce: Int) extends Command case object Beat extends Command }
Example 28
Source File: WordShuffler.scala From streamee with Apache License 2.0 | 5 votes |
package io.moia.streamee.demo import akka.actor.typed.{ ActorRef, Behavior } import akka.actor.typed.scaladsl.Behaviors import akka.stream.Materializer import io.moia.streamee.{ IntoableProcessor, Process, ProcessSinkRef, Step } import org.slf4j.LoggerFactory import scala.annotation.tailrec import scala.util.Random object WordShuffler { final case class ShuffleWord(word: String) final case class WordShuffled(word: String) def apply(): Process[ShuffleWord, WordShuffled] = Process[ShuffleWord, WordShuffled] .via(shuffleWordToString) .via(shuffle) .via(stringToWordShuffled) def shuffleWordToString[Ctx]: Step[ShuffleWord, String, Ctx] = Step[ShuffleWord, Ctx].map(_.word) def shuffle[Ctx]: Step[String, String, Ctx] = Step[String, Ctx].map(shuffleWord) def stringToWordShuffled[Ctx]: Step[String, WordShuffled, Ctx] = Step[String, Ctx].map(WordShuffled) private def shuffleWord(word: String) = { @tailrec def loop(word: String, acc: String = ""): String = if (word.isEmpty) acc else { val (left, right) = word.splitAt(Random.nextInt(word.length)) val c = right.head val nextWord = left + right.tail loop(nextWord, c +: acc) } if (word.length <= 3) word else word.head +: loop(word.tail.init) :+ word.last } } object WordShufflerRunner { import WordShuffler._ sealed trait Command final case class GetProcessSinkRef(replyTo: ActorRef[ProcessSinkRef[ShuffleWord, WordShuffled]]) extends Command final case object Shutdown extends Command private final case object Stop extends Command private val logger = LoggerFactory.getLogger(getClass) def apply()(implicit mat: Materializer): Behavior[Command] = Behaviors.setup { context => import context.executionContext val self = context.self val wordShufflerProcessor = IntoableProcessor(WordShuffler(), "word-shuffler") wordShufflerProcessor.whenDone.onComplete { reason => if (logger.isWarnEnabled) logger.warn(s"Process completed: $reason") self ! Stop } Behaviors.receiveMessagePartial { case GetProcessSinkRef(replyTo) => replyTo ! wordShufflerProcessor.sinkRef() Behaviors.same case Shutdown => wordShufflerProcessor.shutdown() Behaviors.receiveMessagePartial { case Stop => Behaviors.stopped } } } }
Example 29
Source File: OledClusterVisualizer.scala From Pi-Akka-Cluster with Apache License 2.0 | 5 votes |
package akkapi.cluster import akka.actor.typed.scaladsl.Behaviors import akka.actor.typed.{ActorRef, Behavior} import akkapi.cluster.ClusterStatusTracker.{IsLeader, IsNoLeader, NodeDown, NodeExiting, NodeJoining, NodeLeaving, NodeRemoved, NodeState, NodeUnreachable, NodeUp, NodeWeaklyUp, PiClusterSingletonNotRunning, PiClusterSingletonRunning} object OledClusterVisualizer { def apply(screenNumber: Int, settings: Settings, oledDriver: ActorRef[OledDriver.Command]): Behavior[NodeState] = Behaviors.setup { context => new OledClusterVisualizer(screenNumber, settings, oledDriver).running( nodes = Map.empty[Int, String], leader = None ) } } class OledClusterVisualizer private(screenNumber: Int, settings: Settings, oledDriver: ActorRef[OledDriver.Command]) { private val thisHost = settings.config.getString("akka.remote.artery.canonical.hostname") private def updateState(nodeId: Int, status: String)(implicit nodes: Map[Int, String]): Map[Int, String] = { nodes + (nodeId -> status) } def running(implicit nodes: Map[Int, String], leader: Option[Int] ): Behavior[NodeState] = Behaviors .receiveMessage[NodeState] { case NodeUp(nodeLedId) => setClusterViewState(updateState(nodeLedId, "Up")) case NodeJoining(nodeLedId) => setClusterViewState(updateState(nodeLedId, "Joining")) case NodeLeaving(nodeLedId) => setClusterViewState(updateState(nodeLedId, "Left")) case NodeExiting(nodeLedId) => setClusterViewState(updateState(nodeLedId, "Exited")) case NodeRemoved(nodeLedId) => setClusterViewState(updateState(nodeLedId, "Removed")) case NodeDown(nodeLedId) => setClusterViewState(updateState(nodeLedId, "Down")) case NodeUnreachable(nodeLedId) => setClusterViewState(updateState(nodeLedId, "Unreachable")) case NodeWeaklyUp(nodeLedId) => setClusterViewState(updateState(nodeLedId, "Weakly Up")) case IsLeader => setLeader(Some(settings.HostToLedMapping(thisHost))) case IsNoLeader(address) => setLeader(address) case PiClusterSingletonRunning => Behaviors.same case PiClusterSingletonNotRunning => Behaviors.same } private def render(nodes: Map[Int, String], leader: Option[Int]): String = { val stringBuilder = new StringBuilder //TODO (0 to 2).foreach(i => stringBuilder ++= "Node " + i + ": " + nodes.getOrElse(i, "N/A") + "\n") stringBuilder ++= "Leader: " + leader.getOrElse("N/A") stringBuilder.toString() } private def setClusterViewState(nodes: Map[Int, String]) (implicit leader: Option[Int]): Behavior[NodeState] = { oledDriver ! OledDriver.UpdateView(screenNumber, render(nodes, leader)) running(nodes, leader) } private def setLeader(leader: Option[Int]) (implicit nodes: Map[Int, String]): Behavior[NodeState] = { oledDriver ! OledDriver.UpdateView(screenNumber, render(nodes, leader)) running(nodes, leader) } }
Example 30
Source File: Mass.scala From fusion-data with Apache License 2.0 | 5 votes |
package mass import akka.actor.typed.scaladsl.adapter._ import akka.actor.typed.{ ActorRef, ActorSystem, Behavior, Props } import akka.{ actor => classic } import com.typesafe.config.Config import fusion.common.config.FusionConfigFactory import fusion.common.{ ReceptionistFactory, SpawnFactory } import fusion.core.extension.FusionCore import helloscala.common.Configuration import mass.core.Constants import scala.concurrent.ExecutionContext final class Mass private (val classicSystem: classic.ActorSystem) extends SpawnFactory with ReceptionistFactory { implicit def executionContext: ExecutionContext = classicSystem.dispatcher val configuration: Configuration = FusionCore(classicSystem).configuration override def typedSystem: ActorSystem[_] = classicSystem.toTyped override def spawn[T](behavior: Behavior[T], props: Props): ActorRef[T] = classicSystem.spawnAnonymous(behavior, props) override def spawn[T](behavior: Behavior[T], name: String, props: Props): ActorRef[T] = classicSystem.spawn(behavior, name, props) } object Mass { def fromMergedConfig(config: Config): Mass = fromActorSystem(classic.ActorSystem(Constants.MASS, config)) private[mass] def fromActorSystem(system: classic.ActorSystem): Mass = new Mass(system) def fromConfig(originalConfig: Config): Mass = { val config = FusionConfigFactory.arrangeConfig(originalConfig, Constants.MASS, Seq("akka")) fromMergedConfig(config) } }
Example 31
Source File: JobActor.scala From fusion-data with Apache License 2.0 | 5 votes |
package mass.job.service.job import akka.actor.typed.scaladsl.{ ActorContext, Behaviors } import akka.actor.typed.{ ActorRef, ActorSystem, Behavior } import akka.cluster.typed.{ ClusterSingleton, ClusterSingletonSettings, SingletonActor } import fusion.inject.guice.GuiceApplication import fusion.json.CborSerializable import helloscala.common.IntStatus import mass.core.Constants import mass.job.JobScheduler import mass.job.service.job.JobActor.CommandReply import mass.message.job._ import scala.concurrent.Future object JobActor { sealed trait Command extends CborSerializable final case class CommandReply(message: JobMessage, replyTo: ActorRef[JobResponse]) extends Command final case class CommandEvent(event: JobEvent) extends Command val NAME = "job" def init(system: ActorSystem[_]): ActorRef[Command] = { ClusterSingleton(system).init( SingletonActor(apply(), NAME).withSettings(ClusterSingletonSettings(system).withRole(Constants.Roles.CONSOLE))) } private def apply(): Behavior[Command] = Behaviors.setup[Command](context => new JobActor(context).init()) } import mass.job.service.job.JobActor._ class JobActor private (context: ActorContext[Command]) extends JobServiceComponent { import context.executionContext override val jobScheduler: JobScheduler = GuiceApplication(context.system).instance[JobScheduler] def init(): Behavior[Command] = { receive() } def receive(): Behavior[Command] = Behaviors.receiveMessage[Command] { case CommandReply(message, replyTo) => receiveMessage(message).foreach(resp => replyTo ! resp) Behaviors.same case CommandEvent(event) => receiveEvent(event) Behaviors.same } private def receiveMessage(message: JobMessage): Future[JobResponse] = try { val future = message match { case req: JobScheduleReq => handleScheduleJob(req) case req: JobPageReq => handlePage(req) case req: JobFindReq => handleFind(req) case req: JobUploadJobReq => handleUploadJob(req) case req: JobListReq => handleList(req) case req: JobGetAllOptionReq => Future(handleGetAllOption(req)) case req: JobCreateReq => handleCreateJob(req) case req: JobUpdateReq => handleUpdate(req) case req: JobUploadFilesReq => handleUploadFiles(req) } future.recover { case e => val message = s"Handle message error: ${e.getMessage}." logger.error(message, e) JobErrorResponse(IntStatus.INTERNAL_ERROR, message) } } catch { case e: Throwable => val message = s"Process message error: ${e.getMessage}." logger.error(message) Future.successful(JobErrorResponse(IntStatus.INTERNAL_ERROR, message)) } private def receiveEvent(v: JobEvent): Unit = try { v match { case event: JobTriggerEvent => triggerJob(event) } } catch { case e: Throwable => logger.error(s"Process event error: ${e.getMessage}", e) } }
Example 32
Source File: LagSim.scala From kafka-lag-exporter with Apache License 2.0 | 5 votes |
package com.lightbend.kafkalagexporter.integration import akka.actor.Cancellable import akka.actor.typed.scaladsl.Behaviors import akka.actor.typed.{Behavior, PostStop} import akka.kafka.{CommitterSettings, Subscriptions} import akka.kafka.scaladsl.{Committer, Consumer} import akka.kafka.testkit.scaladsl.KafkaSpec import akka.stream.OverflowStrategy import akka.stream.scaladsl.Keep import akka.stream.testkit.scaladsl.TestSink import org.scalatest.concurrent.ScalaFutures import scala.concurrent.Await import scala.concurrent.duration._ trait LagSim extends KafkaSpec with ScalaFutures { private implicit val patience: PatienceConfig = PatienceConfig(30.seconds, 1.second) class LagSimulator(topic: String, group: String) { private var offset: Int = 0 private val committerSettings = CommitterSettings(system).withMaxBatch(1).withParallelism(1) private lazy val (consumerControl, consumerProbe) = Consumer .committableSource(consumerDefaults.withGroupId(group), Subscriptions.topics(topic)) .buffer(size = 1, OverflowStrategy.backpressure) .map { elem => log.debug("Committing elem with offset: {}", elem.committableOffset.partitionOffset) elem.committableOffset.commitScaladsl() } .toMat(TestSink.probe)(Keep.both) .run() def produceElements(num: Int): Unit = { Await.result(produce(topic, offset to (offset + num)), remainingOrDefault) offset += num + 1 } // TODO: Replace this with regular Kafka Consumer for more fine-grained control over committing def consumeElements(num: Int): Unit = { consumerProbe .request(num) .expectNextN(num) } def shutdown(): Unit = { consumerControl.shutdown().futureValue consumerProbe.cancel() } } sealed trait Simulator case class Tick(produce: Int, consume: Int) extends Simulator def lagSimActor(simulator: LagSimulator, scheduledTick: Cancellable = Cancellable.alreadyCancelled): Behavior[Simulator] = Behaviors.receive[Simulator] { case (context, tick @ Tick(produce, consume)) => simulator.produceElements(produce) simulator.consumeElements(consume) lagSimActor(simulator, context.scheduleOnce(1 second, context.self, tick)) } receiveSignal { case (_, PostStop) => simulator.shutdown() scheduledTick.cancel() Behaviors.same } }
Example 33
Source File: KafkaClusterManager.scala From kafka-lag-exporter with Apache License 2.0 | 5 votes |
package com.lightbend.kafkalagexporter import akka.actor.typed.scaladsl.Behaviors import akka.actor.typed.{ActorRef, Behavior, ChildFailed} import akka.util.Timeout import com.lightbend.kafkalagexporter.KafkaClient.KafkaClientContract import com.lightbend.kafkalagexporter.watchers.Watcher import scala.concurrent.duration._ import scala.util.{Failure, Success} object KafkaClusterManager { sealed trait Message sealed trait Stop extends Message final case object Stop extends Stop sealed trait Done extends Message final case object Done extends Done final case class ClusterAdded(c: KafkaCluster) extends Message final case class ClusterRemoved(c: KafkaCluster) extends Message final case class NamedCreator(name: String, creator: () => MetricsSink) private val stopTimeout: Timeout = 3.seconds def init( appConfig: AppConfig, metricsSinks: List[NamedCreator], clientCreator: KafkaCluster => KafkaClientContract): Behavior[Message] = Behaviors.setup { context => context.log.info("Starting Kafka Lag Exporter with configuration: \n{}", appConfig) if (appConfig.clusters.isEmpty && !appConfig.strimziWatcher) context.log.info("No watchers are defined and no clusters are statically configured. Nothing to do.") val watchers: Seq[ActorRef[Watcher.Message]] = Watcher.createClusterWatchers(context, appConfig) val reporters: List[ActorRef[MetricsSink.Message]] = metricsSinks.map { metricsSink : NamedCreator => context.spawn(MetricsReporter.init(metricsSink.creator()), metricsSink.name) } appConfig.clusters.foreach(cluster => context.self ! ClusterAdded(cluster)) reporters.map { context.watch } manager(appConfig, clientCreator, reporters, collectors = Map.empty, watchers) } def manager( appConfig: AppConfig, clientCreator: KafkaCluster => KafkaClientContract, reporters: List[ActorRef[MetricsSink.Message]], collectors: Map[KafkaCluster, ActorRef[ConsumerGroupCollector.Message]], watchers: Seq[ActorRef[Watcher.Message]]): Behavior[Message] = Behaviors.receive[Message] { case (context, ClusterAdded(cluster)) => context.log.info(s"Cluster Added: $cluster") val config = ConsumerGroupCollector.CollectorConfig( appConfig.pollInterval, appConfig.lookupTableSize, cluster ) val collector = context.spawn( ConsumerGroupCollector.init(config, clientCreator, reporters), s"consumer-group-collector-${cluster.name}" ) manager(appConfig, clientCreator, reporters, collectors + (cluster -> collector), watchers) case (context, ClusterRemoved(cluster)) => context.log.info(s"Cluster Removed: $cluster") collectors.get(cluster) match { case Some(collector) => collector ! ConsumerGroupCollector.Stop manager(appConfig, clientCreator, reporters, collectors - cluster, watchers) case None => manager(appConfig, clientCreator, reporters, collectors, watchers) } case (context, _: Stop) => context.log.info("Attempting graceful shutdown") watchers.foreach(_ ! Watcher.Stop) collectors.foreach { case (_, collector) => collector ! ConsumerGroupCollector.Stop } implicit val timeout = stopTimeout reporters.foreach { reporter => context.ask(reporter, (_: ActorRef[MetricsSink.Message]) => MetricsSink.Stop(context.self)) { case Success(_) => Done case Failure(ex) => context.log.error("The metrics reporter shutdown failed.", ex) Done } } Behaviors.same case (_, _: Done) => Behaviors.stopped } receiveSignal { case (context, ChildFailed(`reporters`, cause)) => context.log.error("The metrics reporter failed. Shutting down.", cause) context.self ! Stop Behaviors.same } }
Example 34
Source File: MetricsReporter.scala From kafka-lag-exporter with Apache License 2.0 | 5 votes |
package com.lightbend.kafkalagexporter import akka.actor.typed.Behavior import akka.actor.typed.scaladsl.Behaviors import com.lightbend.kafkalagexporter.MetricsSink._ object MetricsReporter { def init( metricsSink: MetricsSink): Behavior[Message] = Behaviors.setup { _ => reporter(metricsSink) } def reporter(metricsSink: MetricsSink): Behavior[Message] = Behaviors.receive { case (_, m: MetricValue) => metricsSink.report(m) Behaviors.same case (_, rm: RemoveMetric) => metricsSink.remove(rm) Behaviors.same case (context, Stop(sender)) => Behaviors.stopped { () => metricsSink.stop() context.log.info("Gracefully stopped Prometheus metrics endpoint HTTP server") sender ! KafkaClusterManager.Done } case (context, m) => context.log.error(s"Unhandled metric message: $m") Behaviors.same } }
Example 35
Source File: StrimziClusterWatcher.scala From kafka-lag-exporter with Apache License 2.0 | 5 votes |
package com.lightbend.kafkalagexporter.watchers import akka.actor.typed.scaladsl.Behaviors import akka.actor.typed.{ActorRef, Behavior} import com.lightbend.kafkalagexporter.{KafkaCluster, KafkaClusterManager} object StrimziClusterWatcher { val name: String = "strimzi" def init(handler: ActorRef[KafkaClusterManager.Message]): Behavior[Watcher.Message] = Behaviors.setup { context => val watcher = new Watcher.Events { override def added(cluster: KafkaCluster): Unit = handler ! KafkaClusterManager.ClusterAdded(cluster) override def removed(cluster: KafkaCluster): Unit = handler ! KafkaClusterManager.ClusterAdded(cluster) override def error(e: Throwable): Unit = context.log.error(e.getMessage, e) } val client = StrimziClient(watcher) watch(client) } def watch(client: Watcher.Client): Behaviors.Receive[Watcher.Message] = Behaviors.receive { case (context, _: Watcher.Stop) => Behaviors.stopped { () => client.close() context.log.info("Gracefully stopped StrimziKafkaWatcher") } } }
Example 36
Source File: ReadSide.scala From akka-persistence-cassandra with Apache License 2.0 | 5 votes |
package akka.persistence.cassandra.example import akka.actor.typed.pubsub.Topic import akka.actor.typed.scaladsl.Behaviors import akka.actor.typed.{ ActorRef, ActorSystem, Behavior, PostStop } import akka.cluster.sharding.typed.{ ClusterShardingSettings, ShardedDaemonProcessSettings } import akka.cluster.sharding.typed.scaladsl.ShardedDaemonProcess import akka.stream.{ KillSwitches, SharedKillSwitch } import com.typesafe.config.Config import org.HdrHistogram.Histogram import akka.actor.typed.scaladsl.LoggerOps import scala.concurrent.duration._ object ReadSide { sealed trait Command private case object ReportMetrics extends Command object Settings { def apply(config: Config): Settings = Settings(config.getInt("processors"), config.getInt("tags-per-processor")) } case class Settings(nrProcessors: Int, tagsPerProcessor: Int) { val nrTags: Int = nrProcessors * tagsPerProcessor } def apply( system: ActorSystem[_], topic: ActorRef[Topic.Command[ReadSideTopic.ReadSideMetrics]], settings: Settings): Unit = { system.log.info("Running {} processors", settings.nrProcessors) val killSwitch: SharedKillSwitch = KillSwitches.shared("eventProcessorSwitch") ShardedDaemonProcess(system).init( "tag-processor", settings.nrProcessors - 1, // bug that creates +1 processor FIXME remove in 2.6.5 i => behavior(topic, i, settings, killSwitch), ShardedDaemonProcessSettings(system).withShardingSettings(ClusterShardingSettings(system).withRole("read")), None) } private def behavior( topic: ActorRef[Topic.Command[ReadSideTopic.ReadSideMetrics]], nr: Int, settings: Settings, killSwitch: SharedKillSwitch): Behavior[Command] = Behaviors.withTimers { timers => timers.startTimerAtFixedRate(ReportMetrics, 10.second) Behaviors.setup { ctx => val start = (settings.tagsPerProcessor * nr) val end = start + (settings.tagsPerProcessor) - 1 val tags = (start to end).map(i => s"tag-$i") ctx.log.info("Processor {} processing tags {}", nr, tags) // milliseconds, highest value = 1 minute val histogram = new Histogram(10 * 1000 * 60, 2) // maybe easier to just have these as different actors // my thinking is we can start with a large number of tags and scale out // read side processors later // having more tags will also increase write throughput/latency as it'll write to // many partitions // downside is running many streams/queries against c* tags.foreach( tag => new EventProcessorStream[ConfigurablePersistentActor.Event]( ctx.system, ctx.executionContext, s"processor-$nr", tag).runQueryStream(killSwitch, histogram)) Behaviors .receiveMessage[Command] { case ReportMetrics => if (histogram.getTotalCount > 0) { topic ! Topic.Publish( ReadSideTopic.ReadSideMetrics( histogram.getTotalCount, histogram.getMaxValue, histogram.getValueAtPercentile(99), histogram.getValueAtPercentile(50))) histogram.reset() } Behaviors.same } .receiveSignal { case (_, PostStop) => killSwitch.shutdown() Behaviors.same } } } }
Example 37
Source File: Reporter.scala From akka-persistence-cassandra with Apache License 2.0 | 5 votes |
package akka.persistence.cassandra.example import akka.actor.typed.{ ActorRef, Behavior } import akka.actor.typed.pubsub.Topic import akka.actor.typed.scaladsl.Behaviors import akka.persistence.cassandra.example.ReadSideTopic.ReadSideMetrics import akka.actor.typed.scaladsl.LoggerOps object Reporter { def apply(topic: ActorRef[Topic.Command[ReadSideTopic.ReadSideMetrics]]): Behavior[ReadSideMetrics] = Behaviors.setup { ctx => ctx.log.info("Subscribing to latency stats") topic ! Topic.Subscribe(ctx.self) Behaviors.receiveMessage[ReadSideMetrics] { case ReadSideMetrics(count, max, p99, p50) => ctx.log.infoN("Read side Count: {} Max: {} p99: {} p50: {}", count, max, p99, p50) Behaviors.same } } }
Example 38
Source File: LobbyClientActor.scala From lila-ws with GNU Affero General Public License v3.0 | 5 votes |
package lila.ws import akka.actor.typed.scaladsl.Behaviors import akka.actor.typed.{ Behavior, PostStop } import play.api.libs.json.JsValue import ipc._ object LobbyClientActor { import ClientActor._ case class State( idle: Boolean = false, site: ClientActor.State = ClientActor.State() ) def start(deps: Deps): Behavior[ClientMsg] = Behaviors.setup { ctx => import deps._ onStart(deps, ctx) req.user foreach { users.connect(_, ctx.self, silently = true) } services.lobby.connect(req.sri -> req.user.map(_.id)) Bus.subscribe(Bus.channel.lobby, ctx.self) apply(State(), deps) } private def apply(state: State, deps: Deps): Behavior[ClientMsg] = Behaviors .receive[ClientMsg] { (ctx, msg) => import deps._ def forward(payload: JsValue): Unit = lilaIn.lobby(LilaIn.TellSri(req.sri, req.user.map(_.id), payload)) msg match { case ctrl: ClientCtrl => socketControl(state.site, deps, ctrl) case ClientIn.LobbyNonIdle(payload) => if (!state.idle) clientIn(payload) Behaviors.same case ClientIn.OnlyFor(endpoint, payload) => if (endpoint == ClientIn.OnlyFor.Lobby) clientIn(payload) Behaviors.same case in: ClientIn => clientInReceive(state.site, deps, in) match { case None => Behaviors.same case Some(s) => apply(state.copy(site = s), deps) } case msg: ClientOut.Ping => clientIn(services.lobby.pong.get) apply(state.copy(site = sitePing(state.site, deps, msg)), deps) case ClientOut.LobbyForward(payload) => forward(payload) Behaviors.same case ClientOut.Idle(value, payload) => forward(payload) apply(state.copy(idle = value), deps) // default receive (site) case msg: ClientOutSite => val siteState = globalReceive(state.site, deps, ctx, msg) if (siteState == state.site) Behaviors.same else apply(state.copy(site = siteState), deps) case _ => Monitor.clientOutUnhandled("lobby").increment() Behaviors.same } } .receiveSignal { case (ctx, PostStop) => onStop(state.site, deps, ctx) Bus.unsubscribe(Bus.channel.lobby, ctx.self) deps.services.lobby.disconnect(deps.req.sri) Behaviors.same } }
Example 39
Source File: Main.scala From Pi-Akka-Cluster with Apache License 2.0 | 5 votes |
package com.lightbend.akka_oled import akka.NotUsed import akka.actor.typed.scaladsl.Behaviors import akka.actor.typed.scaladsl.adapter.TypedActorSystemOps import akka.actor.typed.{ActorSystem, Behavior, Terminated} import akka.cluster.ddata.LWWMapKey import akka.http.scaladsl.Http import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport import akka.management.scaladsl.AkkaManagement import akka.stream.Materializer import akkapi.cluster.{ClusterStatusTracker, OledClusterVisualizer, OledDriver, Settings} import spray.json.DefaultJsonProtocol object Main extends SprayJsonSupport with DefaultJsonProtocol { case class NodeStatus(status: String) implicit val transactionFormat = jsonFormat1(NodeStatus) def apply(settings: Settings): Behavior[NotUsed] = Behaviors.setup { ctx => val oledDriver = ctx.spawn(OledDriver(settings), "oled-driver") oledDriver ! OledDriver.RegisterView("Cluster State", 0) oledDriver ! OledDriver.RegisterView("Distributed Data State", 1) val clusterView = ctx.spawn(OledClusterVisualizer(0, settings, oledDriver), "oled-cluster-view") val clusterStatusTracker = ctx.spawn(ClusterStatusTracker(settings, None), "cluster-status-tracker") clusterStatusTracker ! ClusterStatusTracker.SubscribeVisualiser(clusterView) val ddataTracker = ctx.spawn( DistributedDataTracker(1, LWWMapKey[String, String]("cache"), oledDriver), "oled-ddata-view") val routes = new Routes(ddataTracker)(ctx.system) implicit val untypedSystem: akka.actor.ActorSystem = ctx.system.toClassic implicit val mat: Materializer = Materializer.createMaterializer(ctx.system.toClassic) Http()(ctx.system.toClassic).bindAndHandle(routes.route, settings.config.getString("cluster-node-configuration.external-ip"), 8080) Behaviors.receiveSignal { case (_, Terminated(_)) => Behaviors.stopped } } } object DisplayDistributedDataMain { def main(args: Array[String]): Unit = { val settings = Settings() val system = ActorSystem[NotUsed](Main(settings), "akka-oled", settings.config) // Start Akka HTTP Management extension AkkaManagement(system).start() } }
Example 40
Source File: ClusterStatusTrackerMain.scala From Pi-Akka-Cluster with Apache License 2.0 | 5 votes |
package akkapi.cluster import akka.NotUsed import akka.actor.typed.scaladsl.Behaviors import akka.actor.typed.scaladsl.adapter.TypedActorSystemOps import akka.actor.typed.{ActorSystem, Behavior, Terminated} import akka.management.scaladsl.AkkaManagement object Main { def apply(settings: Settings): Behavior[NotUsed] = Behaviors.setup { context => val ledStripDriver = context.spawn(LedStripDriver(settings), "led-strip-driver") val ledStripController = context.spawn(LedStripVisualiser(settings, ledStripDriver), "led-strip-controller") val clusterStatusTracker = context.spawn(ClusterStatusTracker(settings, None), "cluster-status-tracker") clusterStatusTracker ! ClusterStatusTracker.SubscribeVisualiser(ledStripController) Behaviors.receiveSignal { case (_, Terminated(_)) => Behaviors.stopped } } } object ClusterStatusTrackerMain { def main(args: Array[String]): Unit = { System.loadLibrary("rpi_ws281x") val settings = Settings() val config = settings.config val system = ActorSystem[NotUsed](Main(settings), settings.actorSystemName, config) // Start Akka HTTP Management extension AkkaManagement(system.toClassic).start() } }
Example 41
Source File: Shop.scala From Learn-Scala-Programming with MIT License | 5 votes |
package ch12 import akka.actor.typed.{ActorRef, ActorSystem, Behavior} import akka.actor.typed.receptionist.{Receptionist, ServiceKey} import akka.actor.typed.scaladsl.{ActorContext, Behaviors} import akka.actor.typed.receptionist.Receptionist._ import ch12.Bakery.Groceries import ch12.Manager.ReceiveGroceries import ch12.Shop.seller import com.typesafe.config.ConfigFactory object Store extends App { val config = ConfigFactory.load("grocery.conf") val system = ActorSystem(seller(Shop.systemReceptionist), "Typed-Bakery", config) } object Shop { final case class ShoppingList(eggs: Int, flour: Int, sugar: Int, chocolate: Int) final case class SellByList(list: ShoppingList, toWhom: ActorRef[Manager.Command]) val SellerKey = ServiceKey[SellByList]("GrocerySeller") type ReceptionistFactory = ActorContext[SellByList] => ActorRef[Receptionist.Command] val systemReceptionist: ReceptionistFactory = _.system.receptionist def seller(receptionist: ReceptionistFactory): Behavior[SellByList] = Behaviors.setup { ctx ⇒ receptionist(ctx) ! Register(SellerKey, ctx.self) Behaviors.receiveMessage[SellByList] { case SellByList(list, toWhom) ⇒ import list._ toWhom ! ReceiveGroceries(Groceries(eggs, flour, sugar, chocolate)) Behaviors.same } } }
Example 42
Source File: Mixer.scala From Learn-Scala-Programming with MIT License | 5 votes |
package ch12 import akka.actor.typed.{ActorRef, Behavior, SupervisorStrategy} import akka.actor.typed.scaladsl.Behaviors import ch12.Bakery.{Groceries, Dough} import ch12.Chef.Collect import scala.concurrent.duration.FiniteDuration import scala.util.Random object Mixer { class MotorOverheatException extends Exception class SlowRotationSpeedException extends Exception class StrongVibrationException extends Exception final case class Mix(groceries: Groceries, sender: ActorRef[Collect]) def mix(mixTime: FiniteDuration): Behavior[Mix] = Behaviors.receive[Mix] { case (ctx, Mix(Groceries(eggs, flour, sugar, chocolate), sender)) => if (Random.nextBoolean()) throw new MotorOverheatException Thread.sleep(mixTime.toMillis) sender ! Collect(Dough(eggs * 50 + flour + sugar + chocolate), ctx.self) Behaviors.stopped } def controlledMix(mixTime: FiniteDuration): Behavior[Mix] = Behaviors .supervise( Behaviors .supervise(Behaviors .supervise(mix(mixTime)) .onFailure[MotorOverheatException](SupervisorStrategy.stop)) .onFailure[SlowRotationSpeedException](SupervisorStrategy.restart)) .onFailure[StrongVibrationException](SupervisorStrategy.resume) }
Example 43
Source File: Chef.scala From Learn-Scala-Programming with MIT License | 5 votes |
package ch12 import akka.actor.typed.scaladsl.Behaviors import akka.actor.typed.{ActorRef, Behavior, DispatcherSelector} import ch12.Bakery.{Groceries, Dough} import ch12.Manager.ReceiveDough object Chef { sealed trait Command final case class Mix(g: Groceries, manager: ActorRef[Manager.Command]) extends Command final case class Collect(p: Dough, mixer: ActorRef[Mixer.Mix]) extends Command final case class BrokenMixer(mixer: ActorRef[Mixer.Mix]) extends Command def idle(mixerFactory: Behavior[Mixer.Mix]): Behaviors.Receive[Command] = Behaviors.receivePartial[Command] { case (context, mix@Mix(Groceries(eggs, flour, sugar, chocolate), manager)) => val mixers = for (i <- 1 to eggs) yield context.spawn(mixerFactory, s"Mixer_$i", DispatcherSelector.fromConfig("mixers-dispatcher")) mixers.foreach(mixer => context.watchWith(mixer, BrokenMixer(mixer))) val msg = Groceries(1, flour / eggs, sugar / eggs, chocolate / eggs) mixers.foreach(_ ! Mixer.Mix(msg, context.self)) mixing(mixers.toSet, 0, manager, mixerFactory) } def mixing(mixers: Set[ActorRef[Mixer.Mix]], collected: Int, manager: ActorRef[Manager.Command], mixerBuilder: Behavior[Mixer.Mix]): Behaviors.Receive[Command] = { def designateBehavior(mixer: ActorRef[Mixer.Mix], doughBuf: Int) = { val mixersToGo = mixers - mixer if (mixersToGo.isEmpty) { manager ! ReceiveDough(Dough(doughBuf)) idle(mixerBuilder) } else { mixing(mixersToGo, doughBuf, manager, mixerBuilder) } } Behaviors.receivePartial { case (context, Collect(dough, mixer)) => val doughBuf = collected + dough.weight context.stop(mixer) designateBehavior(mixer, doughBuf) case (context, BrokenMixer(m)) => context.log.warning("Broken mixer detected {}", m) context.self ! Collect(Dough(0), m) designateBehavior(m, collected) } } }
Example 44
Source File: Baker.scala From Learn-Scala-Programming with MIT License | 5 votes |
package ch12 import akka.actor.typed.{ActorRef, Behavior} import akka.actor.typed.scaladsl.{Behaviors, StashBuffer} import ch12.Bakery.{RawCookies, ReadyCookies} import ch12.Manager.ReceiveReadyCookies import ch12.Oven.{Extract, Put} import scala.concurrent.duration._ object Baker { val DefaultBakingTime: FiniteDuration = 2.seconds private val TimerKey = 'TimerKey sealed trait Command final case class BakeCookies(raw: RawCookies, sender: ActorRef[Manager.Command]) extends Command final case class TooManyCookies(raw: RawCookies) extends Command final case class CookiesReady(cookies: ReadyCookies) extends Command final case object CheckOven extends Command def turnOvenOn: Behavior[Command] = Behaviors.setup { context => val oven = context.spawn(Oven.empty, "Oven") idle(oven) } def idle(oven: ActorRef[Oven.Command]): Behavior[Command] = Behaviors.receivePartial { case (context, BakeCookies(rawCookies, manager)) => oven ! Put(rawCookies.count, context.self) Behaviors.withTimers { timers => timers.startSingleTimer(TimerKey, CheckOven, DefaultBakingTime) baking(oven, manager) } } def baking(oven: ActorRef[Oven.Command], manager: ActorRef[Manager.Command]): Behavior[Command] = Behaviors.setup[Command] { context => val buffer = StashBuffer[Command](capacity = 100) Behaviors.receiveMessage { case CheckOven => oven ! Extract(context.self) Behaviors.same case CookiesReady(cookies) => manager ! ReceiveReadyCookies(cookies) buffer.unstashAll(context, idle(oven)) case c: TooManyCookies=> buffer.stash(BakeCookies(c.raw, manager)) Behaviors.same case c : BakeCookies => buffer.stash(c) Behaviors.same } } }
Example 45
Source File: CustomCache.scala From akka_streams_tutorial with MIT License | 5 votes |
package sample.stream_actor.typed import akka.actor.typed.scaladsl.Behaviors import akka.actor.typed.{ActorRef, Behavior} case class DeviceId(id: String) object CustomCache { sealed trait CacheRequests final case class Get(requestId: String, replyTo: ActorRef[CacheResponses]) extends CacheRequests final case class Devices(devices: List[DeviceId]) extends CacheRequests final case class AddDevices(devices: List[DeviceId]) extends CacheRequests sealed trait CacheResponses final case object EmptyCache extends CacheResponses final case class CachedDevices(devices: List[DeviceId]) extends CacheResponses val empty: Behavior[CacheRequests] = Behaviors.receive[CacheRequests] { (context, message) => message match { case Get(requestId, replyTo) => context.log.info("Empty cache request for requestId {}.", requestId) replyTo ! EmptyCache Behaviors.same case Devices(devices) => context.log.info(s"Initializing cache with: ${devices.size} devices") cached(devices) case AddDevices(devices) => context.log.info(s"Initializing cache with: ${devices.size} devices") cached(devices) } } private def cached(devices: List[DeviceId]): Behavior[CacheRequests] = Behaviors.receive { (context, message) => message match { case Get(requestId, replyTo) => context.log.info("Cache request for requestId {}.", requestId) replyTo ! CachedDevices(devices) Behaviors.same case Devices(updatedDevices) => context.log.info(s"Updating cache with: ${updatedDevices.size} devices") cached(updatedDevices) case AddDevices(updatedDevices) => context.log.info(s"Adding: ${updatedDevices.size} devices.") cached(devices = devices ++ updatedDevices) } } }
Example 46
Source File: BlockingActor.scala From akka_streams_tutorial with MIT License | 5 votes |
package actor import akka.actor.typed.Behavior import akka.actor.typed.scaladsl.Behaviors object BlockingActor { def apply(): Behavior[Int] = Behaviors.receive { (context, i) => context.log.info(s"Started: $i by ${Thread.currentThread().getName}") //block for 5 seconds, representing blocking I/O, etc Thread.sleep(5000) context.log.info(s"Finished: $i") Behaviors.same } }
Example 47
Source File: package.scala From lila-ws with GNU Affero General Public License v3.0 | 5 votes |
package lila import akka.actor.typed.{ ActorRef, ActorSystem, Behavior } package object ws { type Emit[A] = Function[A, Unit] type ClientSystem = ActorSystem[Clients.Control] type ClientBehavior = Behavior[ipc.ClientMsg] type Client = ActorRef[ipc.ClientMsg] type ClientEmit = Emit[ipc.ClientIn] type ~[+A, +B] = Tuple2[A, B] object ~ { def apply[A, B](x: A, y: B) = Tuple2(x, y) def unapply[A, B](x: Tuple2[A, B]): Option[Tuple2[A, B]] = Some(x) } @inline implicit def toOrnicarAddKcombinator[A](any: A) = new ornicarAddKcombinator(any) } final class ornicarAddKcombinator[A](private val any: A) extends AnyVal { def kCombinator(sideEffect: A => Unit): A = { sideEffect(any) any } def ~(sideEffect: A => Unit): A = kCombinator(sideEffect) def pp: A = kCombinator(println) def pp(msg: String): A = kCombinator(a => println(s"[$msg] $a")) }
Example 48
Source File: DistributedDataTracker.scala From Pi-Akka-Cluster with Apache License 2.0 | 5 votes |
package com.lightbend.akka_oled import akka.actor.typed.scaladsl.Behaviors import akka.actor.typed.{ActorRef, Behavior} import akka.cluster.ddata.typed.scaladsl.{DistributedData, Replicator} import akka.cluster.ddata.{LWWMap, LWWMapKey, SelfUniqueAddress} import akkapi.cluster.OledDriver import akkapi.cluster.OledDriver.UpdateView object DistributedDataTracker { sealed trait Command case class UpdateStatus(name: String, status: String) extends Command case class Get(name: String, replyTo: ActorRef[String]) extends Command case class SubscribeResponse(rsp: Replicator.SubscribeResponse[LWWMap[String, String]]) extends Command case class InternalUpdateResponse(rsp: Replicator.UpdateResponse[LWWMap[String, String]]) extends Command private val NO_DATA = "No data" def apply(screenIndex: Int, key: LWWMapKey[String, String], oledDriver: ActorRef[OledDriver.Command]): Behavior[DistributedDataTracker.Command] = Behaviors.setup { context => oledDriver ! UpdateView(screenIndex, NO_DATA) implicit val node: SelfUniqueAddress = DistributedData(context.system).selfUniqueAddress DistributedData.withReplicatorMessageAdapter[Command, LWWMap[String, String]] { replicatorAdapter => replicatorAdapter.subscribe(key, SubscribeResponse.apply) def updated(cachedValue: Map[String, String]): Behavior[Command] = { Behaviors.receiveMessage[Command] { case UpdateStatus(name, status) => replicatorAdapter.askUpdate( askReplyTo => Replicator.Update(key, LWWMap.empty[String, String], Replicator.WriteLocal, askReplyTo)(_ :+ (name -> status)), InternalUpdateResponse.apply) val updatedValue = cachedValue + (name -> status) oledDriver ! UpdateView(screenIndex, renderState(updatedValue)) updated(updatedValue) case Get(name, replyTo) => replyTo ! cachedValue.getOrElse(name, "") Behaviors.same case InternalUpdateResponse(_) => Behaviors.same case SubscribeResponse([email protected](`key`)) => val value = chg.get(key).entries oledDriver ! UpdateView(screenIndex, renderState(value)) updated(value) } } updated(Map.empty[String, String]) } } private def renderState(cachedValue: Map[String, String]): String = { if (cachedValue.nonEmpty) cachedValue.map[String] { case (key, value) => key + ": " + value + " " }.mkString("\n") else NO_DATA } }
Example 49
Source File: ChallengeClientActor.scala From lila-ws with GNU Affero General Public License v3.0 | 5 votes |
package lila.ws import akka.actor.typed.scaladsl.Behaviors import akka.actor.typed.{ Behavior, PostStop } import ipc._ object ChallengeClientActor { import ClientActor._ case class State( owner: Boolean, room: RoomActor.State, site: ClientActor.State = ClientActor.State() ) def start(roomState: RoomActor.State, owner: Boolean, fromVersion: Option[SocketVersion])( deps: Deps ): Behavior[ClientMsg] = Behaviors.setup { ctx => RoomActor.onStart(roomState, fromVersion, deps, ctx) apply(State(owner, roomState), deps) } private def apply(state: State, deps: Deps): Behavior[ClientMsg] = Behaviors .receive[ClientMsg] { (ctx, msg) => import deps._ def receive: PartialFunction[ClientMsg, Behavior[ClientMsg]] = { case in: ClientIn => clientInReceive(state.site, deps, in) match { case None => Behaviors.same case Some(s) => apply(state.copy(site = s), deps) } case ClientCtrl.Disconnect => // lila tries to close the round room, because there's no game with that ID yet // ignore it so we stay connected to the challenge Behaviors.same case ClientCtrl.Broom(oldSeconds) => if (state.site.lastPing < oldSeconds) Behaviors.stopped else { keepAlive challenge state.room.id Behaviors.same } case ctrl: ClientCtrl => socketControl(state.site, deps, ctrl) case ClientOut.ChallengePing => if (state.owner) services.challengePing(state.room.id) Behaviors.same // default receive (site) case msg: ClientOutSite => val siteState = globalReceive(state.site, deps, ctx, msg) if (siteState == state.site) Behaviors.same else apply(state.copy(site = siteState), deps) case _ => Monitor.clientOutUnhandled("challenge").increment() Behaviors.same } RoomActor.receive(state.room, deps).lift(msg).fold(receive(msg)) { case (newState, emit) => emit foreach lilaIn.challenge.apply newState.fold(Behaviors.same[ClientMsg]) { roomState => apply(state.copy(room = roomState), deps) } } } .receiveSignal { case (ctx, PostStop) => onStop(state.site, deps, ctx) RoomActor.onStop(state.room, deps, ctx) Behaviors.same } }
Example 50
Source File: StudyClientActor.scala From lila-ws with GNU Affero General Public License v3.0 | 5 votes |
package lila.ws import akka.actor.typed.scaladsl.Behaviors import akka.actor.typed.{ Behavior, PostStop } import play.api.libs.json.JsValue import ipc._ object StudyClientActor { import ClientActor._ case class State( room: RoomActor.State, site: ClientActor.State = ClientActor.State() ) def start(roomState: RoomActor.State, fromVersion: Option[SocketVersion])( deps: Deps ): Behavior[ClientMsg] = Behaviors.setup { ctx => RoomActor.onStart(roomState, fromVersion, deps, ctx) apply(State(roomState), deps) } private def apply(state: State, deps: Deps): Behavior[ClientMsg] = Behaviors .receive[ClientMsg] { (ctx, msg) => import deps._ def forward(payload: JsValue): Unit = lilaIn.study( LilaIn.TellRoomSri(state.room.id, LilaIn.TellSri(req.sri, req.user.map(_.id), payload)) ) def receive: PartialFunction[ClientMsg, Behavior[ClientMsg]] = { case in: ClientIn => clientInReceive(state.site, deps, in) match { case None => Behaviors.same case Some(s) => apply(state.copy(site = s), deps) } case ClientCtrl.Broom(oldSeconds) => if (state.site.lastPing < oldSeconds) Behaviors.stopped else { keepAlive study state.room.id Behaviors.same } case ctrl: ClientCtrl => socketControl(state.site, deps, ctrl) case ClientOut.StudyForward(payload) => forward(payload) Behaviors.same case anaMove: ClientOut.AnaMove => clientIn(Chess(anaMove)) forward(anaMove.payload) Behaviors.same case anaDrop: ClientOut.AnaDrop => clientIn(Chess(anaDrop)) forward(anaDrop.payload) Behaviors.same case ClientOut.PalantirPing => deps.req.user map { Palantir.respondToPing(state.room.id, _) } foreach clientIn Behaviors.same // default receive (site) case msg: ClientOutSite => val siteState = globalReceive(state.site, deps, ctx, msg) if (siteState == state.site) Behaviors.same else apply(state.copy(site = siteState), deps) case _ => Monitor.clientOutUnhandled("study").increment() Behaviors.same } RoomActor.receive(state.room, deps).lift(msg).fold(receive(msg)) { case (newState, emit) => emit foreach lilaIn.study newState.fold(Behaviors.same[ClientMsg]) { roomState => apply(state.copy(room = roomState), deps) } } } .receiveSignal { case (ctx, PostStop) => onStop(state.site, deps, ctx) RoomActor.onStop(state.room, deps, ctx) Behaviors.same } }
Example 51
Source File: ApiActor.scala From lila-ws with GNU Affero General Public License v3.0 | 5 votes |
package lila.ws import akka.actor.typed.{ Behavior, PostStop } import akka.actor.typed.scaladsl.{ ActorContext, Behaviors } import ipc._ object ApiActor { def start(deps: Deps): Behavior[ClientMsg] = Behaviors.setup { ctx => deps.services.users.connect(deps.user, ctx.self) LilaWsServer.connections.incrementAndGet apply(deps) } def onStop(deps: Deps, ctx: ActorContext[ClientMsg]): Unit = { import deps._ LilaWsServer.connections.decrementAndGet services.users.disconnect(user, ctx.self) services.friends.onClientStop(user.id) } private def apply(deps: Deps): Behavior[ClientMsg] = Behaviors .receive[ClientMsg] { (ctx, msg) => msg match { case ClientCtrl.ApiDisconnect => Behaviors.stopped case _ => Monitor.clientOutUnhandled("api").increment() Behaviors.same } } .receiveSignal { case (ctx, PostStop) => onStop(deps, ctx) Behaviors.same } case class Deps(user: User, services: Services) }
Example 52
Source File: TourClientActor.scala From lila-ws with GNU Affero General Public License v3.0 | 5 votes |
package lila.ws import akka.actor.typed.scaladsl.Behaviors import akka.actor.typed.{ Behavior, PostStop } import ipc._ object TourClientActor { import ClientActor._ case class State( room: RoomActor.State, site: ClientActor.State = ClientActor.State() ) def start(roomState: RoomActor.State, fromVersion: Option[SocketVersion])( deps: Deps ): Behavior[ClientMsg] = Behaviors.setup { ctx => RoomActor.onStart(roomState, fromVersion, deps, ctx) apply(State(roomState), deps) } private def apply(state: State, deps: Deps): Behavior[ClientMsg] = Behaviors .receive[ClientMsg] { (ctx, msg) => import deps._ def receive: PartialFunction[ClientMsg, Behavior[ClientMsg]] = { case in: ClientIn => clientInReceive(state.site, deps, in) match { case None => Behaviors.same case Some(s) => apply(state.copy(site = s), deps) } case ClientCtrl.Broom(oldSeconds) => if (state.site.lastPing < oldSeconds) Behaviors.stopped else { keepAlive.tour(state.room.id) Behaviors.same } case ctrl: ClientCtrl => socketControl(state.site, deps, ctrl) // default receive (site) case msg: ClientOutSite => val siteState = globalReceive(state.site, deps, ctx, msg) if (siteState == state.site) Behaviors.same else apply(state.copy(site = siteState), deps) case _ => Monitor.clientOutUnhandled("tour").increment() Behaviors.same } RoomActor.receive(state.room, deps).lift(msg).fold(receive(msg)) { case (newState, emit) => emit foreach lilaIn.tour newState.fold(Behaviors.same[ClientMsg]) { roomState => apply(state.copy(room = roomState), deps) } } } .receiveSignal { case (ctx, PostStop) => onStop(state.site, deps, ctx) RoomActor.onStop(state.room, deps, ctx) Behaviors.same } }
Example 53
Source File: SimulClientActor.scala From lila-ws with GNU Affero General Public License v3.0 | 5 votes |
package lila.ws import akka.actor.typed.scaladsl.Behaviors import akka.actor.typed.{ Behavior, PostStop } import ipc._ object SimulClientActor { import ClientActor._ case class State( room: RoomActor.State, site: ClientActor.State = ClientActor.State() ) def start(roomState: RoomActor.State, fromVersion: Option[SocketVersion])( deps: Deps ): Behavior[ClientMsg] = Behaviors.setup { ctx => RoomActor.onStart(roomState, fromVersion, deps, ctx) apply(State(roomState), deps) } private def apply(state: State, deps: Deps): Behavior[ClientMsg] = Behaviors .receive[ClientMsg] { (ctx, msg) => import deps._ def receive: PartialFunction[ClientMsg, Behavior[ClientMsg]] = { case in: ClientIn => clientInReceive(state.site, deps, in) match { case None => Behaviors.same case Some(s) => apply(state.copy(site = s), deps) } case ClientCtrl.Broom(oldSeconds) => if (state.site.lastPing < oldSeconds) Behaviors.stopped else { keepAlive.simul(state.room.id) Behaviors.same } case ctrl: ClientCtrl => socketControl(state.site, deps, ctrl) // default receive (site) case msg: ClientOutSite => val siteState = globalReceive(state.site, deps, ctx, msg) if (siteState == state.site) Behaviors.same else apply(state.copy(site = siteState), deps) case _ => Monitor.clientOutUnhandled("simul").increment() Behaviors.same } RoomActor.receive(state.room, deps).lift(msg).fold(receive(msg)) { case (newState, emit) => emit foreach lilaIn.simul newState.fold(Behaviors.same[ClientMsg]) { roomState => apply(state.copy(room = roomState), deps) } } } .receiveSignal { case (ctx, PostStop) => onStop(state.site, deps, ctx) RoomActor.onStop(state.room, deps, ctx) Behaviors.same } }
Example 54
Source File: SwissClientActor.scala From lila-ws with GNU Affero General Public License v3.0 | 5 votes |
package lila.ws import akka.actor.typed.scaladsl.Behaviors import akka.actor.typed.{ Behavior, PostStop } import ipc._ object SwissClientActor { import ClientActor._ case class State( room: RoomActor.State, site: ClientActor.State = ClientActor.State() ) def start(roomState: RoomActor.State, fromVersion: Option[SocketVersion])( deps: Deps ): Behavior[ClientMsg] = Behaviors.setup { ctx => RoomActor.onStart(roomState, fromVersion, deps, ctx) apply(State(roomState), deps) } private def apply(state: State, deps: Deps): Behavior[ClientMsg] = Behaviors .receive[ClientMsg] { (ctx, msg) => import deps._ def receive: PartialFunction[ClientMsg, Behavior[ClientMsg]] = { case in: ClientIn => clientInReceive(state.site, deps, in) match { case None => Behaviors.same case Some(s) => apply(state.copy(site = s), deps) } case ClientCtrl.Broom(oldSeconds) => if (state.site.lastPing < oldSeconds) Behaviors.stopped else { keepAlive.swiss(state.room.id) Behaviors.same } case ctrl: ClientCtrl => socketControl(state.site, deps, ctrl) // default receive (site) case msg: ClientOutSite => val siteState = globalReceive(state.site, deps, ctx, msg) if (siteState == state.site) Behaviors.same else apply(state.copy(site = siteState), deps) case _ => Monitor.clientOutUnhandled("swiss").increment() Behaviors.same } RoomActor.receive(state.room, deps).lift(msg).fold(receive(msg)) { case (newState, emit) => emit foreach lilaIn.swiss newState.fold(Behaviors.same[ClientMsg]) { roomState => apply(state.copy(room = roomState), deps) } } } .receiveSignal { case (ctx, PostStop) => onStop(state.site, deps, ctx) RoomActor.onStop(state.room, deps, ctx) Behaviors.same } }
Example 55
Source File: SiteClientActor.scala From lila-ws with GNU Affero General Public License v3.0 | 5 votes |
package lila.ws import akka.actor.typed.scaladsl.Behaviors import akka.actor.typed.{ Behavior, PostStop } import ipc._ object SiteClientActor { import ClientActor._ def start(deps: Deps): Behavior[ClientMsg] = Behaviors.setup { ctx => import deps._ onStart(deps, ctx) req.user foreach { users.connect(_, ctx.self) } apply(State(), deps) } private def apply(state: State, deps: Deps): Behavior[ClientMsg] = Behaviors .receive[ClientMsg] { (ctx, msg) => msg match { case ctrl: ClientCtrl => socketControl(state, deps, ctrl) case in: ClientIn => clientInReceive(state, deps, in) match { case None => Behaviors.same case Some(s) => apply(s, deps) } case msg: ClientOutSite => val newState = globalReceive(state, deps, ctx, msg) if (newState == state) Behaviors.same else apply(newState, deps) case _ => Monitor.clientOutUnhandled("site").increment() Behaviors.same } } .receiveSignal { case (ctx, PostStop) => onStop(state, deps, ctx) Behaviors.same } }
Example 56
Source File: TeamClientActor.scala From lila-ws with GNU Affero General Public License v3.0 | 5 votes |
package lila.ws import akka.actor.typed.scaladsl.Behaviors import akka.actor.typed.{ Behavior, PostStop } import ipc._ object TeamClientActor { import ClientActor._ case class State( room: RoomActor.State, site: ClientActor.State = ClientActor.State() ) def start(roomState: RoomActor.State, fromVersion: Option[SocketVersion])( deps: Deps ): Behavior[ClientMsg] = Behaviors.setup { ctx => RoomActor.onStart(roomState, fromVersion, deps, ctx) apply(State(roomState), deps) } private def apply(state: State, deps: Deps): Behavior[ClientMsg] = Behaviors .receive[ClientMsg] { (ctx, msg) => import deps._ def receive: PartialFunction[ClientMsg, Behavior[ClientMsg]] = { case in: ClientIn => clientInReceive(state.site, deps, in) match { case None => Behaviors.same case Some(s) => apply(state.copy(site = s), deps) } case ClientCtrl.Broom(oldSeconds) => if (state.site.lastPing < oldSeconds) Behaviors.stopped else { keepAlive.team(state.room.id) Behaviors.same } case ctrl: ClientCtrl => socketControl(state.site, deps, ctrl) // default receive (site) case msg: ClientOutSite => val siteState = globalReceive(state.site, deps, ctx, msg) if (siteState == state.site) Behaviors.same else apply(state.copy(site = siteState), deps) case _ => Monitor.clientOutUnhandled("team").increment() Behaviors.same } RoomActor.receive(state.room, deps).lift(msg).fold(receive(msg)) { case (newState, emit) => emit foreach lilaIn.team newState.fold(Behaviors.same[ClientMsg]) { roomState => apply(state.copy(room = roomState), deps) } } } .receiveSignal { case (ctx, PostStop) => onStop(state.site, deps, ctx) RoomActor.onStop(state.room, deps, ctx) Behaviors.same } }
Example 57
Source File: PiClusterSingleton.scala From Pi-Akka-Cluster with Apache License 2.0 | 5 votes |
package akkapi.cluster import akka.actor.typed.scaladsl.{ActorContext, Behaviors} import akka.actor.typed.{ActorRef, Behavior, PostStop} object PiClusterSingleton { sealed trait Command final case object Ping extends Command def apply(settings: Settings, clusterStatusTracker: ActorRef[ClusterStatusTracker.ClusterEvent]): Behavior[Command] = { Behaviors.setup { context => new PiClusterSingleton(context, settings, clusterStatusTracker).run() } } } class PiClusterSingleton private (context: ActorContext[PiClusterSingleton.Command], settings: Settings, clusterStatusTracker: ActorRef[ClusterStatusTracker.ClusterEvent]) { import PiClusterSingleton._ // Cluster singleton has been started on this node clusterStatusTracker ! ClusterStatusTracker.PiClusterSingletonOnNode def run(): Behavior[Command] = Behaviors.receiveMessage[Command] { case Ping => context.log.info(s"PiClusterSingleton was pinged") Behaviors.same }.receiveSignal { case (_, signal) if signal == PostStop => clusterStatusTracker ! ClusterStatusTracker.PiClusterSingletonNotOnNode Behaviors.same } }
Example 58
Source File: LedPulser.scala From Pi-Akka-Cluster with Apache License 2.0 | 5 votes |
package akkapi.cluster import akka.actor.typed.scaladsl.{ActorContext, Behaviors, TimerScheduler} import akka.actor.typed.{ActorRef, Behavior} import org.neopixel.Neopixel import scala.concurrent.duration.FiniteDuration object LedPulser { sealed trait Command final case class PulseLed(ledNumber: Int, color: Long, flashDuration: FiniteDuration, overRunColor: Option[Long]) extends Command private final case class StopPulse(ledNumber: Int) extends Command def apply(settings: Settings, ledStripDriver: ActorRef[LedStripDriver.Command]): Behavior[Command] = Behaviors.setup { context => Behaviors.withTimers { timers => new LedPulser(settings, context, timers, ledStripDriver).run(Neopixel.Black) } } } class LedPulser(settings: Settings, context: ActorContext[LedPulser.Command], timers: TimerScheduler[LedPulser.Command], ledStripDriver: ActorRef[LedStripDriver.Command]) { import LedPulser._ def run(currentColor: Long): Behavior[Command] = Behaviors.receiveMessagePartial { case PulseLed(ledNumber, color, flashDuration, overRunColor) if color != currentColor => timers.startTimerWithFixedDelay(StopPulse(ledNumber), flashDuration) ledStripDriver ! LedStripDriver.SetLedState(ledNumber, color, None) run(color) case PulseLed(ledNumber, color, flashDuration, overRunColor) => // If the new color is the same as the current color, it implies that // the timer is still running. Obviously, no need to update the color // on the LED. Running `startTimerWithFixedDelay` will cancel the current // timer and start a "fresh" one timers.startTimerWithFixedDelay(StopPulse(ledNumber), flashDuration) run(color) case StopPulse(ledNumber) => ledStripDriver ! LedStripDriver.SetLedState(ledNumber, Neopixel.Black, None) run(Neopixel.Black) } }
Example 59
Source File: ClusterStatusTrackerMain.scala From Pi-Akka-Cluster with Apache License 2.0 | 5 votes |
package akkapi.cluster import akka.NotUsed import akka.actor.typed.scaladsl.adapter.TypedActorSystemOps import akka.actor.typed.scaladsl.{ActorContext, Behaviors} import akka.actor.typed.{ActorSystem, Behavior, Terminated} import akka.management.scaladsl.AkkaManagement object Main { def apply(settings: Settings): Behavior[NotUsed] = Behaviors.setup { context => val ledStripDriver = context.spawn(LedStripDriver(settings), "led-strip-driver") val ledStripController = context.spawn(LedStripVisualiser(settings, ledStripDriver), "led-strip-controller") val clusterStatusTracker = context.spawn( ClusterStatusTracker( settings, Some(contextToClusterSingleton(settings)) ), "cluster-status-tracker" ) clusterStatusTracker ! ClusterStatusTracker.SubscribeVisualiser(ledStripController) Behaviors.receiveSignal { case (_, Terminated(_)) => Behaviors.stopped } } private def contextToClusterSingleton(settings: Settings): ActorContextToSingletonBehavior = (context: ActorContext[ClusterStatusTracker.ClusterEvent]) => PiClusterSingleton(settings, context.self) type ActorContextToSingletonBehavior = ActorContext[ClusterStatusTracker.ClusterEvent] => Behavior[PiClusterSingleton.Command] } object ClusterStatusTrackerMain { def main(args: Array[String]): Unit = { System.loadLibrary("rpi_ws281x") val settings = Settings() val config = settings.config val system = ActorSystem[NotUsed](Main(settings), settings.actorSystemName, config) // Start Akka HTTP Management extension AkkaManagement(system.toClassic).start() } }
Example 60
Source File: PiClusterSingleton.scala From Pi-Akka-Cluster with Apache License 2.0 | 5 votes |
package akkapi.cluster import akka.actor.typed.scaladsl.{ActorContext, Behaviors} import akka.actor.typed.{ActorRef, Behavior, PostStop} object PiClusterSingleton { sealed trait Command final case object Ping extends Command def apply(settings: Settings, clusterStatusTracker: ActorRef[ClusterStatusTracker.ClusterEvent]): Behavior[Command] = { Behaviors.setup { context => new PiClusterSingleton(context, settings, clusterStatusTracker).run() } } } class PiClusterSingleton private (context: ActorContext[PiClusterSingleton.Command], settings: Settings, clusterStatusTracker: ActorRef[ClusterStatusTracker.ClusterEvent]) { import PiClusterSingleton._ // Cluster singleton has been started on this node clusterStatusTracker ! ClusterStatusTracker.PiClusterSingletonOnNode def run(): Behavior[Command] = Behaviors.receiveMessage[Command] { case Ping => context.log.info(s"PiClusterSingleton was pinged") Behaviors.same }.receiveSignal { case (_, signal) if signal == PostStop => clusterStatusTracker ! ClusterStatusTracker.PiClusterSingletonNotOnNode Behaviors.same } }
Example 61
Source File: ClusterStatusTrackerMain.scala From Pi-Akka-Cluster with Apache License 2.0 | 5 votes |
package akkapi.cluster import akka.NotUsed import akka.actor.typed.scaladsl.adapter.TypedActorSystemOps import akka.actor.typed.scaladsl.{ActorContext, Behaviors} import akka.actor.typed.{ActorSystem, Behavior, Terminated} import akka.management.cluster.bootstrap.ClusterBootstrap import akka.management.scaladsl.AkkaManagement object Main { def apply(settings: Settings): Behavior[NotUsed] = Behaviors.setup { context => val ledStripDriver = context.spawn(LedStripDriver(settings), "led-strip-driver") val ledStripController = context.spawn(LedStripVisualiser(settings, ledStripDriver), "led-strip-controller") val clusterStatusTracker = context.spawn( ClusterStatusTracker( settings, Some(contextToClusterSingleton(settings)) ), "cluster-status-tracker" ) clusterStatusTracker ! ClusterStatusTracker.SubscribeVisualiser(ledStripController) Behaviors.receiveSignal { case (_, Terminated(_)) => Behaviors.stopped } } private def contextToClusterSingleton(settings: Settings): ActorContextToSingletonBehavior = (context: ActorContext[ClusterStatusTracker.ClusterEvent]) => PiClusterSingleton(settings, context.self) type ActorContextToSingletonBehavior = ActorContext[ClusterStatusTracker.ClusterEvent] => Behavior[PiClusterSingleton.Command] } object ClusterStatusTrackerMain { def main(args: Array[String]): Unit = { System.loadLibrary("rpi_ws281x") val settings = Settings() val config = settings.config val system = ActorSystem[NotUsed](Main(settings), settings.actorSystemName, config) // Start Akka HTTP Management extension AkkaManagement(system.toClassic).start() ClusterBootstrap(system.toClassic).start() } }
Example 62
Source File: PiClusterSingleton.scala From Pi-Akka-Cluster with Apache License 2.0 | 5 votes |
package akkapi.cluster import akka.actor.typed.scaladsl.{ActorContext, Behaviors} import akka.actor.typed.{ActorRef, Behavior, PostStop} object PiClusterSingleton { sealed trait Command final case object Ping extends Command def apply(settings: Settings, clusterStatusTracker: ActorRef[ClusterStatusTracker.ClusterEvent]): Behavior[Command] = { Behaviors.setup { context => new PiClusterSingleton(context, settings, clusterStatusTracker).run() } } } class PiClusterSingleton private (context: ActorContext[PiClusterSingleton.Command], settings: Settings, clusterStatusTracker: ActorRef[ClusterStatusTracker.ClusterEvent]) { import PiClusterSingleton._ // Cluster singleton has been started on this node clusterStatusTracker ! ClusterStatusTracker.PiClusterSingletonOnNode def run(): Behavior[Command] = Behaviors.receiveMessage[Command] { case Ping => context.log.info(s"PiClusterSingleton was pinged") Behaviors.same }.receiveSignal { case (_, signal) if signal == PostStop => clusterStatusTracker ! ClusterStatusTracker.PiClusterSingletonNotOnNode Behaviors.same } }
Example 63
Source File: ClusterStatusTrackerMain.scala From Pi-Akka-Cluster with Apache License 2.0 | 5 votes |
package akkapi.cluster import akka.NotUsed import akka.actor.typed.scaladsl.adapter.TypedActorSystemOps import akka.actor.typed.scaladsl.{ActorContext, Behaviors} import akka.actor.typed.{ActorSystem, Behavior, Terminated} import akka.management.scaladsl.AkkaManagement object Main { def apply(settings: Settings): Behavior[NotUsed] = Behaviors.setup { context => val ledStripDriver = context.spawn(LedStripDriver(settings), "led-strip-driver") val ledStripController = context.spawn(LedStripVisualiser(settings, ledStripDriver), "led-strip-controller") val clusterStatusTracker = context.spawn( ClusterStatusTracker( settings, Some(contextToClusterSingleton(settings)) ), "cluster-status-tracker" ) clusterStatusTracker ! ClusterStatusTracker.SubscribeVisualiser(ledStripController) Behaviors.receiveSignal { case (_, Terminated(_)) => Behaviors.stopped } } private def contextToClusterSingleton(settings: Settings): ActorContextToSingletonBehavior = (context: ActorContext[ClusterStatusTracker.ClusterEvent]) => PiClusterSingleton(settings, context.self) type ActorContextToSingletonBehavior = ActorContext[ClusterStatusTracker.ClusterEvent] => Behavior[PiClusterSingleton.Command] } object ClusterStatusTrackerMain { def main(args: Array[String]): Unit = { System.loadLibrary("rpi_ws281x") val settings = Settings() val config = settings.config val system = ActorSystem[NotUsed](Main(settings), settings.actorSystemName, config) // Start Akka HTTP Management extension AkkaManagement(system.toClassic).start() } }
Example 64
Source File: PiClusterSingleton.scala From Pi-Akka-Cluster with Apache License 2.0 | 5 votes |
package akkapi.cluster import akka.actor.typed.scaladsl.{ActorContext, Behaviors} import akka.actor.typed.{ActorRef, Behavior, PostStop} object PiClusterSingleton { sealed trait Command final case object Ping extends Command def apply(settings: Settings, clusterStatusTracker: ActorRef[ClusterStatusTracker.ClusterEvent]): Behavior[Command] = { Behaviors.setup { context => new PiClusterSingleton(context, settings, clusterStatusTracker).run() } } } class PiClusterSingleton private (context: ActorContext[PiClusterSingleton.Command], settings: Settings, clusterStatusTracker: ActorRef[ClusterStatusTracker.ClusterEvent]) { import PiClusterSingleton._ // Cluster singleton has been started on this node clusterStatusTracker ! ClusterStatusTracker.PiClusterSingletonOnNode def run(): Behavior[Command] = Behaviors.receiveMessage[Command] { case Ping => context.log.info(s"PiClusterSingleton was pinged") Behaviors.same }.receiveSignal { case (_, signal) if signal == PostStop => clusterStatusTracker ! ClusterStatusTracker.PiClusterSingletonNotOnNode Behaviors.same } }
Example 65
Source File: ClusterStatusTrackerMain.scala From Pi-Akka-Cluster with Apache License 2.0 | 5 votes |
package akkapi.cluster import akka.NotUsed import akka.actor.typed.scaladsl.adapter.TypedActorSystemOps import akka.actor.typed.scaladsl.{ActorContext, Behaviors} import akka.actor.typed.{ActorSystem, Behavior, Terminated} import akka.management.scaladsl.AkkaManagement object Main { def apply(settings: Settings): Behavior[NotUsed] = Behaviors.setup { context => val ledStripDriver = context.spawn(LedStripDriver(settings), "led-strip-driver") val ledStripController = context.spawn(LedStripVisualiser(settings, ledStripDriver), "led-strip-controller") val clusterStatusTracker = context.spawn( ClusterStatusTracker( settings, Some(contextToClusterSingleton(settings)) ), "cluster-status-tracker" ) clusterStatusTracker ! ClusterStatusTracker.SubscribeVisualiser(ledStripController) Behaviors.receiveSignal { case (_, Terminated(_)) => Behaviors.stopped } } private def contextToClusterSingleton(settings: Settings): ActorContextToSingletonBehavior = (context: ActorContext[ClusterStatusTracker.ClusterEvent]) => PiClusterSingleton(settings, context.self) type ActorContextToSingletonBehavior = ActorContext[ClusterStatusTracker.ClusterEvent] => Behavior[PiClusterSingleton.Command] } object ClusterStatusTrackerMain { def main(args: Array[String]): Unit = { System.loadLibrary("rpi_ws281x") val settings = Settings() val config = settings.config val system = ActorSystem[NotUsed](Main(settings), settings.actorSystemName, config) // Start Akka HTTP Management extension AkkaManagement(system.toClassic).start() } }
Example 66
Source File: TriggerRunner.scala From daml with Apache License 2.0 | 5 votes |
// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. // SPDX-License-Identifier: Apache-2.0 package com.daml.lf.engine.trigger import akka.actor.typed.{Behavior, PostStop} import akka.actor.typed.scaladsl.AbstractBehavior import akka.actor.typed.SupervisorStrategy._ import akka.actor.typed.Signal import akka.actor.typed.scaladsl.Behaviors import akka.actor.typed.scaladsl.ActorContext import akka.stream.Materializer import com.typesafe.scalalogging.StrictLogging import com.daml.grpc.adapter.ExecutionSequencerFactory class InitializationHalted(s: String) extends Exception(s) {} class InitializationException(s: String) extends Exception(s) {} object TriggerRunner { type Config = TriggerRunnerImpl.Config trait Message final case object Stop extends Message def apply(config: Config, name: String)( implicit esf: ExecutionSequencerFactory, mat: Materializer): Behavior[TriggerRunner.Message] = Behaviors.setup(ctx => new TriggerRunner(ctx, config, name)) } class TriggerRunner( ctx: ActorContext[TriggerRunner.Message], config: TriggerRunner.Config, name: String)(implicit esf: ExecutionSequencerFactory, mat: Materializer) extends AbstractBehavior[TriggerRunner.Message](ctx) with StrictLogging { import TriggerRunner.{Message, Stop} // Spawn a trigger runner impl. Supervise it. Stop immediately on // initialization halted exceptions, retry any initialization or // execution failure exceptions. private val child = ctx.spawn( Behaviors .supervise( Behaviors .supervise(TriggerRunnerImpl(config)) .onFailure[InitializationHalted](stop) ) .onFailure( restartWithBackoff( config.restartConfig.minRestartInterval, config.restartConfig.maxRestartInterval, config.restartConfig.restartIntervalRandomFactor)), name ) override def onMessage(msg: Message): Behavior[Message] = Behaviors.receiveMessagePartial[Message] { case Stop => Behaviors.stopped // Automatically stops the child actor if running. } override def onSignal: PartialFunction[Signal, Behavior[Message]] = { case PostStop => logger.info(s"Trigger $name stopped") this } }
Example 67
Source File: ClusterStatusTrackerMain.scala From Pi-Akka-Cluster with Apache License 2.0 | 5 votes |
package akkapi.cluster import akka.NotUsed import akka.actor.typed.scaladsl.adapter.TypedActorSystemOps import akka.actor.typed.scaladsl.{ActorContext, Behaviors} import akka.actor.typed.{ActorSystem, Behavior, Terminated} import akka.management.cluster.bootstrap.ClusterBootstrap import akka.management.scaladsl.AkkaManagement object Main { def apply(settings: Settings): Behavior[NotUsed] = Behaviors.setup { context => val ledStripDriver = context.spawn(LedStripDriver(settings), "led-strip-driver") val ledStripController = context.spawn(LedStripVisualiser(settings, ledStripDriver), "led-strip-controller") val clusterStatusTracker = context.spawn( ClusterStatusTracker( settings, Some(contextToClusterSingleton(settings)) ), "cluster-status-tracker" ) clusterStatusTracker ! ClusterStatusTracker.SubscribeVisualiser(ledStripController) Behaviors.receiveSignal { case (_, Terminated(_)) => Behaviors.stopped } } private def contextToClusterSingleton(settings: Settings): ActorContextToSingletonBehavior = (context: ActorContext[ClusterStatusTracker.ClusterEvent]) => PiClusterSingleton(settings, context.self) type ActorContextToSingletonBehavior = ActorContext[ClusterStatusTracker.ClusterEvent] => Behavior[PiClusterSingleton.Command] } object ClusterStatusTrackerMain { def main(args: Array[String]): Unit = { System.loadLibrary("rpi_ws281x") val settings = Settings() val config = settings.config val system = ActorSystem[NotUsed](Main(settings), settings.actorSystemName, config) // Start Akka HTTP Management extension AkkaManagement(system.toClassic).start() ClusterBootstrap(system.toClassic).start() } }
Example 68
Source File: PiClusterSingleton.scala From Pi-Akka-Cluster with Apache License 2.0 | 5 votes |
package akkapi.cluster import akka.actor.typed.scaladsl.{ActorContext, Behaviors} import akka.actor.typed.{ActorRef, Behavior, PostStop} object PiClusterSingleton { sealed trait Command final case object Ping extends Command def apply(settings: Settings, clusterStatusTracker: ActorRef[ClusterStatusTracker.ClusterEvent]): Behavior[Command] = { Behaviors.setup { context => new PiClusterSingleton(context, settings, clusterStatusTracker).run() } } } class PiClusterSingleton private (context: ActorContext[PiClusterSingleton.Command], settings: Settings, clusterStatusTracker: ActorRef[ClusterStatusTracker.ClusterEvent]) { import PiClusterSingleton._ // Cluster singleton has been started on this node clusterStatusTracker ! ClusterStatusTracker.PiClusterSingletonOnNode def run(): Behavior[Command] = Behaviors.receiveMessage[Command] { case Ping => context.log.info(s"PiClusterSingleton was pinged") Behaviors.same }.receiveSignal { case (_, signal) if signal == PostStop => clusterStatusTracker ! ClusterStatusTracker.PiClusterSingletonNotOnNode Behaviors.same } }
Example 69
Source File: ClusterStatusTrackerMain.scala From Pi-Akka-Cluster with Apache License 2.0 | 5 votes |
package akkapi.cluster import akka.NotUsed import akka.actor.typed.scaladsl.adapter.TypedActorSystemOps import akka.actor.typed.scaladsl.{ActorContext, Behaviors} import akka.actor.typed.{ActorSystem, Behavior, Terminated} import akka.management.scaladsl.AkkaManagement object Main { def apply(settings: Settings): Behavior[NotUsed] = Behaviors.setup { context => val ledStripDriver = context.spawn(LedStripDriver(settings), "led-strip-driver") val ledStripController = context.spawn(LedStripVisualiser(settings, ledStripDriver), "led-strip-controller") val clusterStatusTracker = context.spawn( ClusterStatusTracker( settings, Some(contextToClusterSingleton(settings)) ), "cluster-status-tracker" ) clusterStatusTracker ! ClusterStatusTracker.SubscribeVisualiser(ledStripController) Behaviors.receiveSignal { case (_, Terminated(_)) => Behaviors.stopped } } private def contextToClusterSingleton(settings: Settings): ActorContextToSingletonBehavior = (context: ActorContext[ClusterStatusTracker.ClusterEvent]) => PiClusterSingleton(settings, context.self) type ActorContextToSingletonBehavior = ActorContext[ClusterStatusTracker.ClusterEvent] => Behavior[PiClusterSingleton.Command] } object ClusterStatusTrackerMain { def main(args: Array[String]): Unit = { System.loadLibrary("rpi_ws281x") val settings = Settings() val config = settings.config val system = ActorSystem[NotUsed](Main(settings), settings.actorSystemName, config) // Start Akka HTTP Management extension AkkaManagement(system.toClassic).start() } }
Example 70
Source File: PiClusterSingleton.scala From Pi-Akka-Cluster with Apache License 2.0 | 5 votes |
package akkapi.cluster import akka.actor.typed.scaladsl.{ActorContext, Behaviors} import akka.actor.typed.{ActorRef, Behavior, PostStop} object PiClusterSingleton { sealed trait Command final case object Ping extends Command def apply(settings: Settings, clusterStatusTracker: ActorRef[ClusterStatusTracker.ClusterEvent]): Behavior[Command] = { Behaviors.setup { context => new PiClusterSingleton(context, settings, clusterStatusTracker).run() } } } class PiClusterSingleton private (context: ActorContext[PiClusterSingleton.Command], settings: Settings, clusterStatusTracker: ActorRef[ClusterStatusTracker.ClusterEvent]) { import PiClusterSingleton._ // Cluster singleton has been started on this node clusterStatusTracker ! ClusterStatusTracker.PiClusterSingletonOnNode def run(): Behavior[Command] = Behaviors.receiveMessage[Command] { case Ping => context.log.info(s"PiClusterSingleton was pinged") Behaviors.same }.receiveSignal { case (_, signal) if signal == PostStop => clusterStatusTracker ! ClusterStatusTracker.PiClusterSingletonNotOnNode Behaviors.same } }
Example 71
Source File: ClusterStatusTrackerMain.scala From Pi-Akka-Cluster with Apache License 2.0 | 5 votes |
package akkapi.cluster import akka.NotUsed import akka.actor.typed.scaladsl.adapter.TypedActorSystemOps import akka.actor.typed.scaladsl.{ActorContext, Behaviors} import akka.actor.typed.{ActorSystem, Behavior, Terminated} import akka.management.scaladsl.AkkaManagement object Main { def apply(settings: Settings): Behavior[NotUsed] = Behaviors.setup { context => val ledStripDriver = context.spawn(LedStripDriver(settings), "led-strip-driver") val ledStripController = context.spawn(LedStripVisualiser(settings, ledStripDriver), "led-strip-controller") val clusterStatusTracker = context.spawn( ClusterStatusTracker( settings, Some(contextToClusterSingleton(settings)) ), "cluster-status-tracker" ) clusterStatusTracker ! ClusterStatusTracker.SubscribeVisualiser(ledStripController) Behaviors.receiveSignal { case (_, Terminated(_)) => Behaviors.stopped } } private def contextToClusterSingleton(settings: Settings): ActorContextToSingletonBehavior = (context: ActorContext[ClusterStatusTracker.ClusterEvent]) => PiClusterSingleton(settings, context.self) type ActorContextToSingletonBehavior = ActorContext[ClusterStatusTracker.ClusterEvent] => Behavior[PiClusterSingleton.Command] } object ClusterStatusTrackerMain { def main(args: Array[String]): Unit = { System.loadLibrary("rpi_ws281x") val settings = Settings() val config = settings.config val system = ActorSystem[NotUsed](Main(settings), settings.actorSystemName, config) // Start Akka HTTP Management extension AkkaManagement(system.toClassic).start() } }
Example 72
Source File: PiClusterSingleton.scala From Pi-Akka-Cluster with Apache License 2.0 | 5 votes |
package akkapi.cluster import akka.actor.typed.scaladsl.{ActorContext, Behaviors} import akka.actor.typed.{ActorRef, Behavior, PostStop} object PiClusterSingleton { sealed trait Command final case object Ping extends Command def apply(settings: Settings, clusterStatusTracker: ActorRef[ClusterStatusTracker.ClusterEvent]): Behavior[Command] = { Behaviors.setup { context => new PiClusterSingleton(context, settings, clusterStatusTracker).run() } } } class PiClusterSingleton private (context: ActorContext[PiClusterSingleton.Command], settings: Settings, clusterStatusTracker: ActorRef[ClusterStatusTracker.ClusterEvent]) { import PiClusterSingleton._ // Cluster singleton has been started on this node clusterStatusTracker ! ClusterStatusTracker.PiClusterSingletonOnNode def run(): Behavior[Command] = Behaviors.receiveMessage[Command] { case Ping => context.log.info(s"PiClusterSingleton was pinged") Behaviors.same }.receiveSignal { case (_, signal) if signal == PostStop => clusterStatusTracker ! ClusterStatusTracker.PiClusterSingletonNotOnNode Behaviors.same } }
Example 73
Source File: ClusterStatusTrackerMain.scala From Pi-Akka-Cluster with Apache License 2.0 | 5 votes |
package akkapi.cluster import akka.NotUsed import akka.actor.typed.scaladsl.adapter.TypedActorSystemOps import akka.actor.typed.scaladsl.{ActorContext, Behaviors} import akka.actor.typed.{ActorSystem, Behavior, Terminated} import akka.management.scaladsl.AkkaManagement object Main { def apply(settings: Settings): Behavior[NotUsed] = Behaviors.setup { context => val ledStripDriver = context.spawn(LedStripDriver(settings), "led-strip-driver") val ledStripController = context.spawn(LedStripVisualiser(settings, ledStripDriver), "led-strip-controller") val clusterStatusTracker = context.spawn( ClusterStatusTracker( settings, Some(contextToClusterSingleton(settings)) ), "cluster-status-tracker" ) clusterStatusTracker ! ClusterStatusTracker.SubscribeVisualiser(ledStripController) Behaviors.receiveSignal { case (_, Terminated(_)) => Behaviors.stopped } } private def contextToClusterSingleton(settings: Settings): ActorContextToSingletonBehavior = (context: ActorContext[ClusterStatusTracker.ClusterEvent]) => PiClusterSingleton(settings, context.self) type ActorContextToSingletonBehavior = ActorContext[ClusterStatusTracker.ClusterEvent] => Behavior[PiClusterSingleton.Command] } object ClusterStatusTrackerMain { def main(args: Array[String]): Unit = { System.loadLibrary("rpi_ws281x") val settings = Settings() val config = settings.config val system = ActorSystem[NotUsed](Main(settings), settings.actorSystemName, config) // Start Akka HTTP Management extension AkkaManagement(system.toClassic).start() } }
Example 74
Source File: PiClusterSingleton.scala From Pi-Akka-Cluster with Apache License 2.0 | 5 votes |
package akkapi.cluster import akka.actor.typed.scaladsl.{ActorContext, Behaviors} import akka.actor.typed.{ActorRef, Behavior, PostStop} object PiClusterSingleton { sealed trait Command final case object Ping extends Command def apply(settings: Settings, clusterStatusTracker: ActorRef[ClusterStatusTracker.ClusterEvent]): Behavior[Command] = { Behaviors.setup { context => new PiClusterSingleton(context, settings, clusterStatusTracker).run() } } } class PiClusterSingleton private (context: ActorContext[PiClusterSingleton.Command], settings: Settings, clusterStatusTracker: ActorRef[ClusterStatusTracker.ClusterEvent]) { import PiClusterSingleton._ // Cluster singleton has been started on this node clusterStatusTracker ! ClusterStatusTracker.PiClusterSingletonOnNode def run(): Behavior[Command] = Behaviors.receiveMessage[Command] { case Ping => context.log.info(s"PiClusterSingleton was pinged") Behaviors.same }.receiveSignal { case (_, signal) if signal == PostStop => clusterStatusTracker ! ClusterStatusTracker.PiClusterSingletonNotOnNode Behaviors.same } }