akka.actor.typed.ActorRef Scala Examples
The following examples show how to use akka.actor.typed.ActorRef.
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: 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 2
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 3
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 4
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 5
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 6
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 7
Source File: Main.scala From akka-persistence-cassandra with Apache License 2.0 | 5 votes |
package akka.persistence.cassandra.example import akka.actor.typed.{ ActorRef, ActorSystem } import akka.actor.typed.scaladsl.Behaviors import akka.cluster.sharding.typed.ShardingEnvelope import akka.cluster.typed.{ Cluster, SelfUp, Subscribe } import akka.management.cluster.bootstrap.ClusterBootstrap import akka.management.scaladsl.AkkaManagement import akka.persistence.cassandra.example.LoadGenerator.Start import akka.actor.typed.scaladsl.LoggerOps import akka.stream.alpakka.cassandra.scaladsl.CassandraSessionRegistry import scala.concurrent.Await import scala.concurrent.duration._ object Main { def main(args: Array[String]): Unit = { ActorSystem(Behaviors.setup[SelfUp] { ctx => val readSettings = ReadSide.Settings(ctx.system.settings.config.getConfig("cassandra.example")) val writeSettings = ConfigurablePersistentActor.Settings(readSettings.nrTags) val loadSettings = LoadGenerator.Settings(ctx.system.settings.config.getConfig("cassandra.example")) AkkaManagement(ctx.system).start() ClusterBootstrap(ctx.system).start() val cluster = Cluster(ctx.system) cluster.subscriptions ! Subscribe(ctx.self, classOf[SelfUp]) val topic = ReadSideTopic.init(ctx) if (cluster.selfMember.hasRole("read")) { val session = CassandraSessionRegistry(ctx.system).sessionFor("akka.persistence.cassandra") val offsetTableStmt = """ CREATE TABLE IF NOT EXISTS akka.offsetStore ( eventProcessorId text, tag text, timeUuidOffset timeuuid, PRIMARY KEY (eventProcessorId, tag) ) """ Await.ready(session.executeDDL(offsetTableStmt), 30.seconds) } Behaviors.receiveMessage { case SelfUp(state) => ctx.log.infoN( "Cluster member joined. Initializing persistent actors. Roles {}. Members {}", cluster.selfMember.roles, state.members) val ref = ConfigurablePersistentActor.init(writeSettings, ctx.system) if (cluster.selfMember.hasRole("read")) { ctx.spawnAnonymous(Reporter(topic)) } ReadSide(ctx.system, topic, readSettings) if (cluster.selfMember.hasRole("load")) { ctx.log.info("Starting load generation") val load = ctx.spawn(LoadGenerator(loadSettings, ref), "load-generator") load ! Start(10.seconds) } Behaviors.empty } }, "apc-example") } }
Example 8
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 9
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 10
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 11
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 12
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 13
Source File: Watcher.scala From kafka-lag-exporter with Apache License 2.0 | 5 votes |
package com.lightbend.kafkalagexporter.watchers import akka.actor.typed.ActorRef import akka.actor.typed.scaladsl.ActorContext import com.lightbend.kafkalagexporter.{AppConfig, KafkaCluster} import com.lightbend.kafkalagexporter.KafkaClusterManager object Watcher { sealed trait Message sealed trait Stop extends Message final case object Stop extends Stop trait Client { def close(): Unit } trait Events { def added(cluster: KafkaCluster): Unit def removed(cluster: KafkaCluster): Unit def error(e: Throwable): Unit } def createClusterWatchers(context: ActorContext[KafkaClusterManager.Message], appConfig: AppConfig): Seq[ActorRef[Watcher.Message]] = { // Add additional watchers here.. val configMap = Seq(StrimziClusterWatcher.name -> appConfig.strimziWatcher) configMap.flatMap { case (StrimziClusterWatcher.name, true) => context.log.info(s"Adding watcher: ${StrimziClusterWatcher.name}") Seq(context.spawn(StrimziClusterWatcher.init(context.self), s"strimzi-cluster-watcher-${StrimziClusterWatcher.name}")) case _ => Seq() } } }
Example 14
Source File: MetricsSink.scala From kafka-lag-exporter with Apache License 2.0 | 5 votes |
package com.lightbend.kafkalagexporter import akka.actor.typed.ActorRef import com.lightbend.kafkalagexporter.MetricsSink._ object MetricsSink { trait Message final case class Stop(sender: ActorRef[KafkaClusterManager.Message]) extends MetricsSink.Message final case class GaugeDefinition(name: String, help: String, labels: List[String]) type MetricDefinitions = List[GaugeDefinition] trait ClusterMetric extends Metric{ def clusterName: String } trait Metric { def labels: List[String] def definition: GaugeDefinition } trait MetricValue extends ClusterMetric { def value: Double } trait RemoveMetric extends ClusterMetric } trait MetricsSink { def report(m: MetricValue): Unit def remove(m: RemoveMetric): Unit def stop(): Unit = () }
Example 15
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 16
Source File: JobService.scala From fusion-data with Apache License 2.0 | 5 votes |
package mass.job.service.job import java.io.File import java.nio.charset.StandardCharsets import java.nio.file.{ Files, Path } import akka.actor.typed.{ ActorRef, ActorSystem } import akka.actor.typed.scaladsl.AskPattern._ import akka.http.scaladsl.server.directives.FileInfo import akka.util.Timeout import javax.inject.{ Inject, Singleton } import mass.job.service.job.JobActor.CommandReply import mass.message.job._ import scala.collection.immutable import scala.concurrent.duration._ import scala.concurrent.{ ExecutionContext, Future } import scala.reflect.ClassTag @Singleton class JobService @Inject() (implicit system: ActorSystem[_]) { implicit val timeout: Timeout = Timeout(10.seconds) val jobActor: ActorRef[JobActor.Command] = JobActor.init(system) def listOption(): Future[JobGetAllOptionResp] = askToJob[JobGetAllOptionResp](JobGetAllOptionReq()) def uploadFiles(list: immutable.Seq[(FileInfo, File)])(implicit ec: ExecutionContext): Future[JobUploadFilesResp] = { askToJob[JobUploadFilesResp](JobUploadFilesReq(list)).andThen { case _ => list.foreach { case (_, file) => Files.deleteIfExists(file.toPath) } } } def uploadJobOnZip(fileInfo: FileInfo, file: Path)(implicit ec: ExecutionContext): Future[JobUploadJobResp] = { val req = JobUploadJobReq( file, fileInfo.fileName, fileInfo.contentType.charsetOption.map(_.nioCharset()).getOrElse(StandardCharsets.UTF_8)) askToJob[JobUploadJobResp](req).andThen { case _ => Files.deleteIfExists(file) } } def updateTrigger(req: JobUpdateReq): Future[JobSchedulerResp] = askToJob[JobSchedulerResp](req) def page(req: JobPageReq): Future[JobPageResp] = askToJob[JobPageResp](req) def findItemByKey(key: String): Future[JobSchedulerResp] = askToJob[JobSchedulerResp](JobFindReq(key = key)) def createJob(req: JobCreateReq): Future[JobCreateResp] = askToJob[JobCreateResp](req) def updateJob(req: JobUpdateReq): Future[JobSchedulerResp] = askToJob[JobSchedulerResp](req) @inline private def askToJob[RESP](req: JobMessage)(implicit tag: ClassTag[RESP]): Future[RESP] = jobActor.ask[JobResponse](replyTo => CommandReply(req, replyTo)).mapTo[RESP] }
Example 17
Source File: ShoppingCartServiceImpl.scala From lagom with Apache License 2.0 | 5 votes |
package com.example.shoppingcart.impl import java.time.OffsetDateTime import akka.Done import akka.NotUsed import com.example.shoppingcart.api.ShoppingCartService import com.lightbend.lagom.scaladsl.api.ServiceCall import com.lightbend.lagom.scaladsl.api.broker.Topic import com.lightbend.lagom.scaladsl.api.transport.BadRequest import com.lightbend.lagom.scaladsl.api.transport.NotFound import com.lightbend.lagom.scaladsl.api.transport.TransportException import com.lightbend.lagom.scaladsl.persistence.EventStreamElement import scala.concurrent.ExecutionContext import akka.cluster.sharding.typed.scaladsl.ClusterSharding import scala.concurrent.duration._ import akka.util.Timeout import akka.cluster.sharding.typed.scaladsl.EntityRef import akka.actor.typed.ActorRef private def entityRef(id: String): EntityRef[ShoppingCartCommand] = clusterSharding.entityRefFor(ShoppingCart.typeKey, id) implicit val timeout = Timeout(5.seconds) override def get(id: String): ServiceCall[NotUsed, String] = ServiceCall { _ => entityRef(id) .ask { reply: ActorRef[Summary] => Get(reply) } .map { cart => asShoppingCartView(id, cart) } } //#akka-persistence-reffor-after override def updateItem(id: String, productId: String, qty: Int): ServiceCall[NotUsed, String] = ServiceCall { update => entityRef(id) .ask { replyTo: ActorRef[Confirmation] => UpdateItem(productId, qty, replyTo) } .map { case Accepted(summary) => asShoppingCartView(id, summary) case Rejected(reason) => throw BadRequest(reason) } } override def checkout(id: String): ServiceCall[NotUsed, String] = ServiceCall { _ => entityRef(id) .ask(replyTo => Checkout(replyTo)) .map { case Accepted(summary) => asShoppingCartView(id, summary) case Rejected(reason) => throw BadRequest(reason) } } private def asShoppingCartView(id: String, cart: Summary): String = { val items = cart.items.map {case (k, v) => s"$k=$v"}.mkString(":") val status = if (cart.checkedOut) "checkedout" else "open" s"$id:$items:$status" } override def getReport(cartId: String): ServiceCall[NotUsed, String] = ServiceCall { _ => reportRepository.findById(cartId).map { case Some(cart) => if (cart.checkedOut) "checkedout" else "open" case None => throw NotFound(s"Couldn't find a shopping cart report for '$cartId'") } } }
Example 18
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 19
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 20
Source File: FromServer.scala From korolev with Apache License 2.0 | 5 votes |
package korolev.data import akka.actor.typed.ActorRef import korolev.internal.Frontend import ujson._ sealed trait FromServer object FromServer { case class Procedure(procedure: Frontend.Procedure, args: List[Any]) extends FromServer object Procedure { def apply(code: Int, args: List[Any]): Procedure = { new Procedure(Frontend.Procedure(code).get, args) } def fromJson(ast: Value): Either[String, Procedure] = try { ast match { case arr: Arr => val Num(procedureId) :: argsAsts = arr.value.toList val code = procedureId.toInt Frontend.Procedure(code) match { case Some(procedure) => val args = argsAsts.collect { case Str(s) => s case Num(n) if n.toString.contains(".") => n.toDouble case Num(n) => n.toInt case False => false case True => true case Null => null } Right(FromServer.Procedure(procedure, args)) case None => Left(s"unknown procedure #$code") } case other => Left(s"Unexpected JSON #$other") } } catch { case e: MatchError => Left(s"can't parse ast $e") } } case class ErrorOccurred(error: Error) extends FromServer case class Connected(ref: ActorRef[ToServer]) extends FromServer case object Closed extends FromServer }
Example 21
Source File: MusicCommands.scala From AckCord with MIT License | 5 votes |
package ackcord.examplecore.music import ackcord._ import ackcord.commands.{CommandBuilder, CommandController, NamedCommand, VoiceGuildMemberCommandMessage} import ackcord.data.{GuildId, TextChannel} import ackcord.examplecore.music.MusicHandler.{NextTrack, QueueUrl, StopMusic, TogglePause} import akka.NotUsed import akka.actor.typed.scaladsl.AskPattern._ import akka.actor.typed.{ActorRef, ActorSystem} import akka.stream.scaladsl.{Flow, Keep, Sink} import akka.stream.typed.scaladsl.ActorFlow import akka.util.Timeout class MusicCommands(requests: Requests, guildId: GuildId, musicHandler: ActorRef[MusicHandler.Command])( implicit timeout: Timeout, system: ActorSystem[Nothing] ) extends CommandController(requests) { val VoiceCommand: CommandBuilder[VoiceGuildMemberCommandMessage, NotUsed] = GuildVoiceCommand.andThen(CommandBuilder.inOneGuild(guildId)) val queue: NamedCommand[String] = VoiceCommand.named("&", Seq("q", "queue")).parsing[String].withSideEffects { m => musicHandler.ask[MusicHandler.CommandAck.type](QueueUrl(m.parsed, m.textChannel, m.voiceChannel.id, _)) } private def simpleCommand( aliases: Seq[String], mapper: (TextChannel, ActorRef[MusicHandler.CommandAck.type]) => MusicHandler.MusicHandlerEvents ): NamedCommand[NotUsed] = { VoiceCommand.andThen(CommandBuilder.inOneGuild(guildId)).named("&", aliases, mustMention = true).toSink { Flow[VoiceGuildMemberCommandMessage[NotUsed]] .map(_.textChannel) .via(ActorFlow.ask(requests.parallelism)(musicHandler)(mapper)) .toMat(Sink.ignore)(Keep.none) } } val stop: NamedCommand[NotUsed] = simpleCommand(Seq("s", "stop"), StopMusic.apply) val next: NamedCommand[NotUsed] = simpleCommand(Seq("n", "next"), NextTrack.apply) val pause: NamedCommand[NotUsed] = simpleCommand(Seq("p", "pause"), TogglePause.apply) }
Example 22
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 23
Source File: TFQueriesAkkaHttpResource.scala From model-serving-tutorial with Apache License 2.0 | 5 votes |
package com.lightbend.modelserving.tensorflowserving import akka.actor.Scheduler import akka.actor.typed.ActorRef import akka.actor.typed.scaladsl.AskPattern._ import akka.http.scaladsl.server.Directives._ import akka.http.scaladsl.server.Route import akka.util.Timeout import com.lightbend.modelserving.model.ModelToServeStats import de.heikoseeberger.akkahttpjackson.JacksonSupport import scala.concurrent.duration._ object TFQueriesAkkaHttpResource extends JacksonSupport { implicit val askTimeout = Timeout(30.seconds) def storeRoutes(modelserver: ActorRef[TFModelServerActor])(implicit scheduler: Scheduler) : Route = get { // Get statistics path("state") { onSuccess(modelserver ? ((replyTo: ActorRef[ModelToServeStats]) => GetState(replyTo))) { case stats : ModelToServeStats => complete(stats) } } } }
Example 24
Source File: TFServingModelServer.scala From model-serving-tutorial with Apache License 2.0 | 5 votes |
package com.lightbend.modelserving.tensorflowserving import akka.actor.typed.scaladsl.Behaviors import akka.actor.typed.scaladsl.adapter._ import akka.actor.typed.{ActorRef, ActorSystem} import akka.http.scaladsl.Http import akka.kafka.scaladsl.Consumer import akka.kafka.{ConsumerSettings, Subscriptions} import akka.stream.scaladsl.Sink import akka.stream.typed.scaladsl.{ActorFlow, ActorMaterializer} import akka.util.Timeout import com.lightbend.modelserving.configuration.ModelServingConfiguration import com.lightbend.modelserving.model.ServingResult import com.lightbend.modelserving.winemodel.DataRecord import org.apache.kafka.clients.consumer.ConsumerConfig import org.apache.kafka.common.serialization.ByteArrayDeserializer import scala.concurrent.duration._ import scala.util.Success object TFServingModelServer { import ModelServingConfiguration._ // Initialization implicit val modelServer = ActorSystem( Behaviors.setup[TFModelServerActor]( context => new TFModelServerBehaviour(context)), "ModelServing") implicit val materializer = ActorMaterializer() implicit val executionContext = modelServer.executionContext implicit val askTimeout = Timeout(30.seconds) // Configuration properties for the Kafka topic. val dataSettings = ConsumerSettings(modelServer.toUntyped, new ByteArrayDeserializer, new ByteArrayDeserializer) .withBootstrapServers(KAFKA_BROKER) .withGroupId(DATA_GROUP) .withProperty(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest") def main(args: Array[String]): Unit = { println(s"Akka application that uses TensorFlow Serving, brokers $KAFKA_BROKER") // Data stream processing Consumer.atMostOnceSource(dataSettings, Subscriptions.topics(DATA_TOPIC)) .map(record => DataRecord.wineFromByteArray(record.value)).collect { case Success(a) => a } .via(ActorFlow.ask(1)(modelServer)((elem, replyTo : ActorRef[Option[ServingResult[Double]]]) => new ServeData(replyTo, elem))) .collect{ case Some(result) => result} .runWith(Sink.foreach(result => println(s"Model served in ${System.currentTimeMillis() - result.submissionTs} ms, with result ${result.result} " + s"(model ${result.name}, data type ${result.dataType})"))) // Rest Server startRest(modelServer) } def startRest(modelServerManager: ActorSystem[TFModelServerActor]): Unit = { implicit val timeout = Timeout(10.seconds) implicit val system = modelServerManager.toUntyped val host = "0.0.0.0" val port = MODELSERVING_PORT val routes = TFQueriesAkkaHttpResource.storeRoutes(modelServerManager)(modelServerManager.scheduler) val _ = Http().bindAndHandle(routes, host, port) map { binding => println(s"Starting models observer on port ${binding.localAddress}") } recover { case ex => println(s"Models observer could not bind to $host:$port - ${ex.getMessage}") } } }
Example 25
Source File: TypedMessages.scala From model-serving-tutorial with Apache License 2.0 | 5 votes |
package com.lightbend.modelserving.akka import akka.Done import akka.actor.typed.ActorRef import com.lightbend.model.winerecord.WineRecord import com.lightbend.modelserving.model.{DataToServe, ModelToServe, ModelToServeStats, ServingResult} // Controller trait ModelServerActor case class UpdateModel(reply: ActorRef[Done], model : ModelToServe) extends ModelServerActor with ModelServerManagerActor case class ScoreData(reply: ActorRef[Option[ServingResult[Double]]], record : DataToServe[WineRecord]) extends ModelServerActor with ModelServerManagerActor case class GetState(reply: ActorRef[ModelToServeStats], dataType : String) extends ModelServerActor with ModelServerManagerActor // Controller manager trait ModelServerManagerActor case class GetModels(reply: ActorRef[GetModelsResult]) extends ModelServerManagerActor // Reply messages case class GetModelsResult(models : Seq[String])
Example 26
Source File: QueriesAkkaHttpResource.scala From model-serving-tutorial with Apache License 2.0 | 5 votes |
package com.lightbend.modelserving.akka import akka.actor.Scheduler import akka.actor.typed.ActorRef import akka.actor.typed.scaladsl.AskPattern._ import akka.http.scaladsl.server.Directives._ import akka.http.scaladsl.server.Route import akka.util.Timeout import com.lightbend.modelserving.model.ModelToServeStats import de.heikoseeberger.akkahttpjackson.JacksonSupport import scala.concurrent.duration._ object QueriesAkkaHttpResource extends JacksonSupport { implicit val askTimeout = Timeout(30.seconds) def storeRoutes(modelserver: ActorRef[ModelServerManagerActor])(implicit scheduler: Scheduler) : Route = get { // Get list of models path("processors") { onSuccess(modelserver ? ((replyTo: ActorRef[GetModelsResult]) => GetModels(replyTo))) { case models: GetModelsResult => complete(models) } } ~ // Get statistics for a given data type path("state"/Segment) { dataType => onSuccess(modelserver ? ((replyTo: ActorRef[ModelToServeStats]) => GetState(replyTo, dataType))) { case stats : ModelToServeStats => complete(stats) } } } }
Example 27
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 28
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 29
Source File: UserRepositorySerializer.scala From whirlwind-tour-akka-typed with Apache License 2.0 | 5 votes |
package de.heikoseeberger.wtat import akka.actor.ExtendedActorSystem import akka.actor.typed.{ ActorRef, ActorRefResolver } import akka.serialization.SerializerWithStringManifest import de.heikoseeberger.wtat.proto.userrepository.{ AddUser => AddUserProto, RemoveUser => RemoveUserProto, UserAdded => UserAddedProto, UserRemoved => UserRemovedProto, UsernameTaken => UsernameTakenProto, UsernameUnknown => UsernameUnknownProto } import de.heikoseeberger.wtat.proto.{ User => UserProto } import java.io.NotSerializableException final class UserRepositorySerializer(system: ExtendedActorSystem) extends SerializerWithStringManifest { import UserRepository._ import akka.actor.typed.scaladsl.adapter._ override val identifier = 4243 private final val AddUserManifest = "AddUser" private final val UsernameTakenManifest = "UsernameTaken" private final val UserAddedManifest = "UserAdded" private final val RemoveUserManifest = "RemoveUser" private final val UsernameUnknownManifest = "UsernameUnknown" private final val UserRemovedManifest = "UserRemoved" private val resolver = ActorRefResolver(system.toTyped) override def manifest(o: AnyRef) = o match { case serializable: Serializable => serializable match { case _: AddUser => AddUserManifest case _: UsernameTaken => UsernameTakenManifest case _: UserAdded => UserAddedManifest case _: RemoveUser => RemoveUserManifest case _: UsernameUnknown => UsernameUnknownManifest case _: UserRemoved => UserRemovedManifest } case _ => throw new IllegalArgumentException(s"Unknown class: ${o.getClass}!") } override def toBinary(o: AnyRef) = { def userProto(user: User) = UserProto(user.username.value, user.nickname.value) def toBinary(ref: ActorRef[_]) = resolver.toSerializationFormat(ref) val proto = o match { case serializable: Serializable => serializable match { case AddUser(user, replyTo) => AddUserProto(Some(userProto(user)), toBinary(replyTo)) case UsernameTaken(username) => UsernameTakenProto(username) case UserAdded(user) => UserAddedProto(Some(userProto(user))) case RemoveUser(username, replyTo) => RemoveUserProto(username, toBinary(replyTo)) case UsernameUnknown(username) => UsernameUnknownProto(username) case UserRemoved(username) => UserRemovedProto(username) } case _ => throw new IllegalArgumentException(s"Unknown class: ${o.getClass}!") } proto.toByteArray } override def fromBinary(bytes: Array[Byte], manifest: String) = { def addUser(proto: AddUserProto) = AddUser(user(proto.user.get), fromBinary(proto.replyTo)) def usernameTaken(proto: UsernameTakenProto) = UsernameTaken(proto.username) def userAdded(proto: UserAddedProto) = UserAdded(user(proto.user.get)) def user(proto: UserProto) = User(proto.username, proto.nickname).valueOr(_.fail) def removeUser(proto: RemoveUserProto) = RemoveUser(proto.username, fromBinary(proto.replyTo)) def usernameUnknown(proto: UsernameUnknownProto) = UsernameUnknown(proto.username) def userRemoved(proto: UserRemovedProto) = UserRemoved(proto.username) def fromBinary(ref: String) = resolver.resolveActorRef(ref) manifest match { case AddUserManifest => addUser(AddUserProto.parseFrom(bytes)) case UsernameTakenManifest => usernameTaken(UsernameTakenProto.parseFrom(bytes)) case UserAddedManifest => userAdded(UserAddedProto.parseFrom(bytes)) case RemoveUserManifest => removeUser(RemoveUserProto.parseFrom(bytes)) case UsernameUnknownManifest => usernameUnknown(UsernameUnknownProto.parseFrom(bytes)) case UserRemovedManifest => userRemoved(UserRemovedProto.parseFrom(bytes)) case _ => throw new NotSerializableException(s"Unknown manifest: $manifest!") } } }
Example 30
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 31
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 32
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 33
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 34
Source File: WsOrderBookState.scala From matcher with MIT License | 5 votes |
package com.wavesplatform.dex.api.ws.state import akka.actor.typed.ActorRef import cats.syntax.option._ import com.wavesplatform.dex.api.ws.entities.{WsLastTrade, WsOrderBookSettings} import com.wavesplatform.dex.api.ws.protocol import com.wavesplatform.dex.api.ws.protocol.WsOrderBookChanges import com.wavesplatform.dex.api.ws.state.WsAddressState.getNextUpdateId import com.wavesplatform.dex.domain.asset.AssetPair import com.wavesplatform.dex.domain.model.Denormalization.{denormalizeAmountAndFee, denormalizePrice} import com.wavesplatform.dex.domain.model.{Amount, Price} import com.wavesplatform.dex.model.{LastTrade, LevelAmounts} import monocle.macros.GenLens import scala.collection.immutable.TreeMap case class WsOrderBookState(wsConnections: Map[ActorRef[WsOrderBookChanges], Long], changedAsks: Set[Price], changedBids: Set[Price], lastTrade: Option[LastTrade], changedTickSize: Option[Double]) { val genLens: GenLens[WsOrderBookState] = GenLens[WsOrderBookState] def addSubscription(x: ActorRef[WsOrderBookChanges]): WsOrderBookState = copy(wsConnections = wsConnections.updated(x, 0L)) def withoutSubscription(x: ActorRef[WsOrderBookChanges]): WsOrderBookState = if (wsConnections.size == 1) WsOrderBookState(Map.empty, Set.empty, Set.empty, None, None) else copy(wsConnections = wsConnections - x) def hasSubscriptions: Boolean = wsConnections.nonEmpty def hasChanges: Boolean = changedAsks.nonEmpty || changedBids.nonEmpty || lastTrade.nonEmpty || changedTickSize.nonEmpty def denormalized(amountDecimals: Int, priceDecimals: Int, xs: TreeMap[Price, Amount]): TreeMap[Double, Double] = xs.map { case (price, amount) => denormalizePrice(price, amountDecimals, priceDecimals).toDouble -> denormalizeAmountAndFee(amount, amountDecimals).toDouble } def lastTrade(amountDecimals: Int, priceDecimals: Int, x: LastTrade): WsLastTrade = WsLastTrade( price = denormalizePrice(x.price, amountDecimals, priceDecimals).toDouble, amount = denormalizeAmountAndFee(x.amount, amountDecimals).toDouble, side = x.side ) def flushed(assetPair: AssetPair, amountDecimals: Int, priceDecimals: Int, asks: TreeMap[Price, Amount], bids: TreeMap[Price, Amount], timestamp: Long): WsOrderBookState = copy( wsConnections = if (hasChanges) { val changes = protocol.WsOrderBookChanges( assetPair = assetPair, asks = denormalized(amountDecimals, priceDecimals, take(asks, changedAsks)), bids = denormalized(amountDecimals, priceDecimals, take(bids, changedBids)), lastTrade = lastTrade.map(lastTrade(amountDecimals, priceDecimals, _)), updateId = 0L, // Will be changed below timestamp = timestamp, settings = if (changedTickSize.isDefined) WsOrderBookSettings(None, changedTickSize).some else None ) wsConnections.map { case (conn, updateId) => val newUpdateId = getNextUpdateId(updateId) conn ! changes.copy(updateId = newUpdateId) conn -> newUpdateId } } else wsConnections, changedAsks = Set.empty, changedBids = Set.empty, lastTrade = None, changedTickSize = None ) def take(xs: TreeMap[Price, Amount], levels: Set[Price]): TreeMap[Price, Amount] = { // 1. Levels will be always smaller, than xs // 2. A level could gone from xs val r = TreeMap.newBuilder[Price, Amount](xs.ordering) levels.foreach { level => r += level -> xs.getOrElse(level, 0L) } r.result() } def accumulateChanges(lc: LevelAmounts, lt: Option[LastTrade], ts: Option[Double]): WsOrderBookState = if (hasSubscriptions) { ( genLens(_.changedAsks).modify(_ ++ lc.asks.keySet) andThen genLens(_.changedBids).modify(_ ++ lc.bids.keySet) andThen genLens(_.lastTrade).modify { if (lt.isEmpty) _ else lt } andThen genLens(_.changedTickSize).modify { if (ts.isEmpty) _ else ts } )(this) } else this }
Example 35
package lila.ws import akka.actor.typed.ActorRef import ipc.ClientMsg object Bus { type Chan = String private val impl = new util.EventBus[ClientMsg, Chan, ActorRef[ClientMsg]]( initialCapacity = 65535, publish = (actor, event) => actor ! event ) def subscribe = impl.subscribe _ def unsubscribe = impl.unsubscribe _ def publish(chan: Chan, event: ClientMsg): Unit = impl.publish(chan, event) def publish(chan: ChanSelect, event: ClientMsg): Unit = impl.publish(chan(channel), event) def publish(msg: Msg): Unit = impl.publish(msg.channel, msg.event) case class Msg(event: ClientMsg, channel: Chan) type ChanSelect = Bus.channel.type => Chan object channel { def sri(s: Sri) = s"sri/${s.value}" def flag(f: Flag) = s"flag/$f" val mlat = "mlat" val all = "all" val lobby = "lobby" val tv = "tv" def userTv(userId: User.ID) = s"userTv/$userId" def room(id: RoomId) = s"room/$id" def tourStanding(id: Tour.ID) = s"tour-standing/$id" def externalChat(id: RoomId) = s"external-chat/$id" } def msg(event: ClientMsg, chan: ChanSelect) = Msg(event, chan(channel)) def size = impl.size def sizeOf(chan: ChanSelect) = impl sizeOf chan(channel) // distinct bus for internal events val internal = new util.EventBus[Any, Chan, PartialFunction[Any, Unit]]( initialCapacity = 16, publish = (listener, event) => listener lift event ) }
Example 36
Source File: Fens.scala From lila-ws with GNU Affero General Public License v3.0 | 5 votes |
package lila.ws import akka.actor.typed.ActorRef import chess.format.{ FEN, Uci } import java.util.concurrent.ConcurrentHashMap import ipc._ object Fens { case class Position(lastUci: Uci, fen: FEN) case class Watched(position: Option[Position], clients: Set[ActorRef[ClientMsg]]) private val games = new ConcurrentHashMap[Game.Id, Watched](1024) // client starts watching def watch(gameIds: Iterable[Game.Id], client: Client): Unit = gameIds foreach { gameId => games .compute( gameId, { case (_, null) => Watched(None, Set(client)) case (_, Watched(pos, clients)) => Watched(pos, clients + client) } ) .position foreach { case Position(lastUci, fen) => client ! ClientIn.Fen(gameId, lastUci, fen) } } // when a client disconnects def unwatch(gameIds: Iterable[Game.Id], client: Client): Unit = gameIds foreach { gameId => games.computeIfPresent( gameId, (_, watched) => { val newClients = watched.clients - client if (newClients.isEmpty) null else watched.copy(clients = newClients) } ) } // move coming from the server def move(gameId: Game.Id, json: JsonString): Unit = { games.computeIfPresent( gameId, (_, watched) => json.value match { case MoveRegex(uciS, fenS) => Uci(uciS).fold(watched) { lastUci => val fen = FEN(fenS) val msg = ClientIn.Fen(gameId, lastUci, fen) watched.clients foreach { _ ! msg } watched.copy(position = Some(Position(lastUci, fen))) } case _ => watched } ) } // ...,"uci":"h2g2","san":"Rg2","fen":"r2qb1k1/p2nbrpn/6Np/3pPp1P/1ppP1P2/2P1B3/PP2B1R1/R2Q1NK1",... private val MoveRegex = """uci":"([^"]+)".+fen":"([^"]+)""".r.unanchored def size = games.size }
Example 37
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 38
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 39
Source File: Boy.scala From Learn-Scala-Programming with MIT License | 5 votes |
package ch12 import akka.actor.typed.ActorRef import akka.actor.typed.scaladsl.Behaviors import ch12.Shop._ object Boy { final case class GoShopping(shoppingList: ShoppingList, seller: ActorRef[SellByList], manager: ActorRef[Manager.Command]) val goShopping = Behaviors.receiveMessage[GoShopping] { case GoShopping(shoppingList, seller, manager) => seller ! SellByList(shoppingList, manager) Behaviors.stopped } }
Example 40
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 41
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 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: Cook.scala From Learn-Scala-Programming with MIT License | 5 votes |
package ch12 import akka.actor.typed.ActorRef import akka.actor.typed.scaladsl.Behaviors import ch12.Bakery.{Dough, RawCookies} import ch12.Manager.ReceiveRawCookies object Cook { final case class FormCookies(dough: Dough, sender: ActorRef[Manager.Command]) val form: Behaviors.Receive[FormCookies] = Behaviors.receiveMessage { case FormCookies(dough, sender) => val numberOfCookies = makeCookies(dough.weight) sender ! ReceiveRawCookies(RawCookies(numberOfCookies)) form } private val cookieWeight = 60 private def makeCookies(weight: Int): Int = weight / cookieWeight }
Example 44
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 45
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 46
Source File: Routes.scala From Pi-Akka-Cluster with Apache License 2.0 | 5 votes |
package com.lightbend.akka_oled import akka.actor.typed.scaladsl.AskPattern._ import akka.actor.typed.{ActorRef, ActorSystem} import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport import akka.http.scaladsl.server.Directives.{as, complete, concat, entity, get, onSuccess, pathPrefix, post, _} import akka.http.scaladsl.server.Route import akka.util.Timeout import com.lightbend.akka_oled.DistributedDataTracker.{Get, UpdateStatus} import com.lightbend.akka_oled.Main.NodeStatus import scala.concurrent.duration._ class Routes(tracker: ActorRef[DistributedDataTracker.Command])(implicit system: ActorSystem[_]) extends SprayJsonSupport { implicit val timeout: Timeout = 8.seconds val route: Route = pathPrefix("status" / "[0-9a-zA-Z]+".r) { node => concat( get { onSuccess(tracker.ask[String](Get(node, _))) { value => complete(value + "\n") } }, post { entity(as[NodeStatus]) { status => tracker ! UpdateStatus(node, status.status) complete("Ok\n") } } ) } }
Example 47
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 48
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 49
Source File: WsAddressState.scala From matcher with MIT License | 5 votes |
package com.wavesplatform.dex.api.ws.state import akka.actor.typed.ActorRef import cats.syntax.option._ import com.wavesplatform.dex.api.ws.entities.{WsBalances, WsOrder} import com.wavesplatform.dex.api.ws.protocol.WsAddressChanges import com.wavesplatform.dex.domain.account.Address import com.wavesplatform.dex.domain.asset.Asset import com.wavesplatform.dex.domain.model.Denormalization._ import com.wavesplatform.dex.domain.order.Order import com.wavesplatform.dex.error.ErrorFormatterContext import com.wavesplatform.dex.model.{AcceptedOrder, OrderStatus} case class WsAddressState(address: Address, activeSubscription: Map[ActorRef[WsAddressChanges], Long], pendingSubscription: Set[ActorRef[WsAddressChanges]], changedSpendableAssets: Set[Asset], changedReservableAssets: Set[Asset], ordersChanges: Map[Order.Id, WsOrder]) { // TODO Probably use an ordered Map and pass it to WsAddressChanges val hasActiveSubscriptions: Boolean = activeSubscription.nonEmpty val hasChanges: Boolean = getAllChangedAssets.nonEmpty || ordersChanges.nonEmpty def getAllChangedAssets: Set[Asset] = changedSpendableAssets ++ changedReservableAssets def getAllOrderChanges: Seq[WsOrder] = ordersChanges.values.toSeq def addPendingSubscription(subscriber: ActorRef[WsAddressChanges]): WsAddressState = copy(pendingSubscription = pendingSubscription + subscriber) def flushPendingSubscriptions(): WsAddressState = copy(activeSubscription = activeSubscription ++ pendingSubscription.iterator.map(_ -> 0L), pendingSubscription = Set.empty) def removeSubscription(subscriber: ActorRef[WsAddressChanges]): WsAddressState = { if (activeSubscription.size == 1) copy(activeSubscription = Map.empty).cleanChanges() else copy(activeSubscription = activeSubscription - subscriber) } def putReservedAssets(diff: Set[Asset]): WsAddressState = copy(changedReservableAssets = changedReservableAssets ++ diff) def putSpendableAssets(diff: Set[Asset]): WsAddressState = copy(changedSpendableAssets = changedSpendableAssets ++ diff) def putOrderUpdate(id: Order.Id, update: WsOrder): WsAddressState = copy(ordersChanges = ordersChanges + (id -> update)) def putOrderStatusUpdate(id: Order.Id, newStatus: OrderStatus): WsAddressState = putOrderUpdate( id = id, update = ordersChanges.getOrElse(id, WsOrder(id)).copy(status = newStatus.name.some) ) def putOrderFillingInfoAndStatusUpdate(ao: AcceptedOrder, newStatus: OrderStatus)(implicit efc: ErrorFormatterContext): WsAddressState = { val ad = efc.assetDecimals(ao.order.assetPair.amountAsset) val pd = efc.assetDecimals(ao.order.assetPair.priceAsset) val fd = efc.assetDecimals(ao.feeAsset) putOrderUpdate( id = ao.id, update = ordersChanges .getOrElse(ao.id, WsOrder(ao.id)) .copy( status = newStatus.name.some, filledAmount = ao.fillingInfo.filledAmount.some.map(denormalizeAmountAndFee(_, ad).toDouble), filledFee = ao.fillingInfo.filledFee.some.map(denormalizeAmountAndFee(_, fd).toDouble), avgWeighedPrice = ao.fillingInfo.avgWeighedPrice.some.map(denormalizePrice(_, ad, pd).toDouble) ) ) } def sendSnapshot(balances: Map[Asset, WsBalances], orders: Seq[WsOrder]): Unit = { val snapshot = WsAddressChanges(address, balances, orders, 0) pendingSubscription.foreach(_ ! snapshot) } def sendDiffs(balances: Map[Asset, WsBalances], orders: Seq[WsOrder]): WsAddressState = copy( activeSubscription = activeSubscription.map { // dirty but one pass case (conn, updateId) => val newUpdateId = WsAddressState.getNextUpdateId(updateId) conn ! WsAddressChanges(address, balances, orders, newUpdateId) conn -> newUpdateId } ) def cleanChanges(): WsAddressState = copy(changedSpendableAssets = Set.empty, changedReservableAssets = Set.empty, ordersChanges = Map.empty) } object WsAddressState { def empty(address: Address): WsAddressState = WsAddressState(address, Map.empty, Set.empty, Set.empty, Set.empty, Map.empty) val numberMaxSafeInteger = 9007199254740991L def getNextUpdateId(currentUpdateId: Long): Long = if (currentUpdateId == numberMaxSafeInteger) 1 else currentUpdateId + 1 }
Example 50
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 51
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 52
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 53
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 54
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 55
Source File: ButtonPushHandlers.scala From Pi-Akka-Cluster with Apache License 2.0 | 5 votes |
package akka_oled import akka.actor.typed.ActorRef import akkapi.cluster.OledDriver import com.pi4j.io.gpio.{GpioController, GpioFactory, GpioPinDigitalInput, PinPullResistance, RaspiPin} import com.pi4j.io.gpio.event.{GpioPinDigitalStateChangeEvent, GpioPinListenerDigital} trait ButtonPushHandlers { val gpio: GpioController = GpioFactory.getInstance val DELAY = 300 var counter = 0 val lastClick = 0 val RESET_DELAY = 1000 private[this] def diff(last: Option[Long]): Long = System.currentTimeMillis() - last.getOrElse(0L) def onStop(): Unit = gpio.removeAllListeners() def initButtonPush(actor: ActorRef[OledDriver.Command]): Unit = { val upButton: GpioPinDigitalInput = gpio.provisionDigitalInputPin(RaspiPin.GPIO_16, PinPullResistance.PULL_UP) upButton.addListener(new GpioPinListenerDigital() { var lastPush: Option[Long] = None override def handleGpioPinDigitalStateChangeEvent(event: GpioPinDigitalStateChangeEvent): Unit = { counter += 1 if (event.getState.isLow && diff(lastPush) > DELAY) { // display pin state on console if(diff(lastPush) < RESET_DELAY){ actor ! OledDriver.FirstScreen } else { actor ! OledDriver.NextScreen } lastPush = Some(System.currentTimeMillis()) } } }) } }
Example 56
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 57
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 58
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 59
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 60
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 61
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 62
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 63
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 } } }