akka.actor.ReceiveTimeout Scala Examples
The following examples show how to use akka.actor.ReceiveTimeout.
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: IngestionHandler.scala From hydra with Apache License 2.0 | 5 votes |
package hydra.ingest.services import akka.actor.SupervisorStrategy.Stop import akka.actor.{Actor, ActorRef, OneForOneStrategy, ReceiveTimeout} import akka.http.scaladsl.model.{StatusCode, StatusCodes} import hydra.core.ingest.{HydraRequest, IngestionReport, RequestParams} import hydra.ingest.services.IngestorRegistry.{ FindAll, FindByName, LookupResult } import scala.concurrent.duration.FiniteDuration trait IngestionHandler { this: Actor => def timeout: FiniteDuration def request: HydraRequest //we require an actorref here for performance reasons def registry: ActorRef private val targetIngestor = request.metadataValue(RequestParams.HYDRA_INGESTOR_PARAM) targetIngestor match { case Some(ingestor) => registry ! FindByName(ingestor) case None => registry ! FindAll } override def receive: Receive = { case LookupResult(Nil) => val errorCode = targetIngestor .map(i => StatusCodes .custom(404, s"No ingestor named $i was found in the registry.") ) .getOrElse(StatusCodes.BadRequest) complete(errorWith(errorCode)) case LookupResult(ingestors) => context.actorOf( IngestionSupervisor.props(request, self, ingestors, timeout) ) case report: IngestionReport => complete(report) } override val supervisorStrategy = OneForOneStrategy() { case e: Exception => fail(e) Stop } private def errorWith(statusCode: StatusCode) = { IngestionReport(request.correlationId, Map.empty, statusCode.intValue()) } def complete(report: IngestionReport) def fail(e: Throwable) }
Example 2
Source File: InitializingActor.scala From hydra with Apache License 2.0 | 5 votes |
package hydra.core.akka import akka.actor.{Actor, ActorRef, ReceiveTimeout, Stash} import akka.pattern.pipe import hydra.common.config.ActorConfigSupport import hydra.common.logging.LoggingAdapter import hydra.core.HydraException import hydra.core.akka.InitializingActor.{InitializationError, Initialized} import hydra.core.protocol.HydraMessage import retry.Success import scala.concurrent.Future import scala.concurrent.duration._ import scala.util.control.NonFatal trait InitializingActor extends Actor with ActorConfigSupport with Stash with LoggingAdapter { def initializationError(ex: Throwable): Receive } object InitializingActor { case object Initialized extends HydraMessage case class InitializationError(cause: Throwable) extends HydraMessage } @SerialVersionUID(1L) class ActorInitializationException( ingestor: ActorRef, message: String, cause: Throwable ) extends HydraException( ActorInitializationException.enrichedMessage(ingestor, message), cause ) { def getActor: ActorRef = ingestor } object ActorInitializationException { private def enrichedMessage(actor: ActorRef, message: String) = Option(actor).map(a => s"${a.path}: $message").getOrElse(message) private[hydra] def apply( actor: ActorRef, message: String, cause: Throwable = null ) = new ActorInitializationException(actor, message, cause) def unapply( ex: ActorInitializationException ): Option[(ActorRef, String, Throwable)] = Some((ex.getActor, ex.getMessage, ex.getCause)) }
Example 3
Source File: SocialMediaStalker.scala From Akka-Cookbook with MIT License | 5 votes |
package com.packt.chapter10 import akka.actor.{Actor, ActorLogging, ActorRef, ReceiveTimeout} import com.packt.chapter10.SocialMediaAggregator.{Report, StartFetching, StopFetching} import scala.collection.mutable import scala.concurrent.duration._ class SocialMediaStalker(aggregator: ActorRef, userId: String) extends Actor with ActorLogging { import context.dispatcher context.setReceiveTimeout(10 seconds) val counts = mutable.Map.empty[String, Int].withDefaultValue(0) override def preStart() = { log.info("Politely asking to aggregate") aggregator ! StartFetching(userId, 1 second) context.system.scheduler.scheduleOnce(5 second, aggregator, StopFetching(userId)) } override def postStop() = { log.info(s"Stopping. Overall counts for $userId: $counts") } def receive = { case Report(list) => val stats = list.groupBy(_.socialNetwork).mapValues(_.map(_.posts.size).sum) log.info(s"New report: $stats") stats.foreach(kv => counts += kv._1 -> (counts(kv._1) + kv._2)) case ReceiveTimeout => context.stop(self) } }
Example 4
Source File: WebsocketSession.scala From graphcool-framework with Apache License 2.0 | 5 votes |
package cool.graph.websockets import java.util.concurrent.TimeUnit import akka.actor.{Actor, ActorRef, PoisonPill, Props, ReceiveTimeout, Stash, Terminated} import cool.graph.akkautil.{LogUnhandled, LogUnhandledExceptions} import cool.graph.bugsnag.BugSnagger import cool.graph.messagebus.QueuePublisher import cool.graph.websockets.protocol.Request import scala.collection.mutable import scala.concurrent.duration._ // if you don't supply your own Protocol (see below) object WebsocketSessionManager { object Requests { case class OpenWebsocketSession(projectId: String, sessionId: String, outgoing: ActorRef) case class CloseWebsocketSession(sessionId: String) case class IncomingWebsocketMessage(projectId: String, sessionId: String, body: String) case class IncomingQueueMessage(sessionId: String, body: String) } object Responses { case class OutgoingMessage(text: String) } } case class WebsocketSessionManager( requestsPublisher: QueuePublisher[Request], bugsnag: BugSnagger ) extends Actor with LogUnhandled with LogUnhandledExceptions { import WebsocketSessionManager.Requests._ val websocketSessions = mutable.Map.empty[String, ActorRef] override def receive: Receive = logUnhandled { case OpenWebsocketSession(projectId, sessionId, outgoing) => val ref = context.actorOf(Props(WebsocketSession(projectId, sessionId, outgoing, requestsPublisher, bugsnag))) context.watch(ref) websocketSessions += sessionId -> ref case CloseWebsocketSession(sessionId) => websocketSessions.get(sessionId).foreach(context.stop) case req: IncomingWebsocketMessage => websocketSessions.get(req.sessionId) match { case Some(session) => session ! req case None => println(s"No session actor found for ${req.sessionId} | ${req.projectId} when processing websocket message. This should only happen very rarely.") } case req: IncomingQueueMessage => websocketSessions.get(req.sessionId) match { case Some(session) => session ! req case None => // Session already closed } case Terminated(terminatedActor) => websocketSessions.retain { case (_, sessionActor) => sessionActor != terminatedActor } } } case class WebsocketSession( projectId: String, sessionId: String, outgoing: ActorRef, requestsPublisher: QueuePublisher[Request], bugsnag: BugSnagger ) extends Actor with LogUnhandled with LogUnhandledExceptions with Stash { import WebsocketSessionManager.Requests._ import WebsocketSessionManager.Responses._ import metrics.SubscriptionWebsocketMetrics._ activeWsConnections.inc context.setReceiveTimeout(FiniteDuration(60, TimeUnit.MINUTES)) def receive: Receive = logUnhandled { case IncomingWebsocketMessage(_, _, body) => requestsPublisher.publish(Request(sessionId, projectId, body)) case IncomingQueueMessage(_, body) => outgoing ! OutgoingMessage(body) case ReceiveTimeout => context.stop(self) } override def postStop = { activeWsConnections.dec outgoing ! PoisonPill requestsPublisher.publish(Request(sessionId, projectId, "STOP")) } }
Example 5
Source File: ClusterShardingQuickTerminationSpec.scala From akka-persistence-cassandra with Apache License 2.0 | 5 votes |
package akka.persistence.cassandra.sharding import akka.actor.{ ActorLogging, ActorRef, Props, ReceiveTimeout } import akka.cluster.{ Cluster, MemberStatus } import akka.cluster.sharding.{ ClusterSharding, ClusterShardingSettings, ShardRegion } import akka.persistence.PersistentActor import akka.persistence.cassandra.CassandraSpec import akka.testkit.TestProbe import scala.concurrent.duration._ object ClusterShardingQuickTerminationSpec { case object Increment case object Decrement final case class Get(counterId: Long) final case class EntityEnvelope(id: Long, payload: Any) case object Ack case object Stop final case class CounterChanged(delta: Int) class Counter extends PersistentActor with ActorLogging { import ShardRegion.Passivate context.setReceiveTimeout(5.seconds) // self.path.name is the entity identifier (utf-8 URL-encoded) override def persistenceId: String = "Counter-" + self.path.name var count = 0 def updateState(event: CounterChanged): Unit = count += event.delta override def receiveRecover: Receive = { case evt: CounterChanged => updateState(evt) case other => log.debug("Other: {}", other) } override def receiveCommand: Receive = { case Increment => persist(CounterChanged(+1))(updateState) case Decrement => persist(CounterChanged(-1))(updateState) case Get(_) => sender() ! count case ReceiveTimeout => context.parent ! Passivate(stopMessage = Stop) case Stop => sender() ! Ack context.stop(self) } } val extractEntityId: ShardRegion.ExtractEntityId = { case EntityEnvelope(id, payload) => (id.toString, payload) case msg @ Get(id) => (id.toString, msg) } val numberOfShards = 100 val extractShardId: ShardRegion.ExtractShardId = { case EntityEnvelope(id, _) => (id % numberOfShards).toString case Get(id) => (id % numberOfShards).toString } } class ClusterShardingQuickTerminationSpec extends CassandraSpec(""" akka.actor.provider = cluster """.stripMargin) { import ClusterShardingQuickTerminationSpec._ "Cassandra Plugin with Cluster Sharding" must { "clear state if persistent actor shuts down" in { Cluster(system).join(Cluster(system).selfMember.address) awaitAssert { Cluster(system).selfMember.status shouldEqual MemberStatus.Up } ClusterSharding(system).start( typeName = "tagging", entityProps = Props[Counter], settings = ClusterShardingSettings(system), extractEntityId = extractEntityId, extractShardId = extractShardId) (0 to 100).foreach { i => val counterRegion: ActorRef = ClusterSharding(system).shardRegion("tagging") awaitAssert { val sender = TestProbe() counterRegion.tell(Get(123), sender.ref) sender.expectMsg(500.millis, i) } counterRegion ! EntityEnvelope(123, Increment) counterRegion ! Get(123) expectMsg(i + 1) counterRegion ! EntityEnvelope(123, Stop) expectMsg(Ack) } } } }
Example 6
Source File: Passivation.scala From akka-dddd-template with Apache License 2.0 | 5 votes |
package com.boldradius.cqrs import akka.actor.{PoisonPill, Actor, ReceiveTimeout} import com.boldradius.util.ALogging import akka.contrib.pattern.ShardRegion.Passivate trait Passivation extends ALogging { this: Actor => protected def passivate(receive: Receive): Receive = receive.orElse{ // tell parent actor to send us a poisinpill case ReceiveTimeout => self.logInfo( s => s" $s ReceiveTimeout: passivating. ") context.parent ! Passivate(stopMessage = PoisonPill) // stop case PoisonPill => context.stop(self.logInfo( s => s" $s PoisonPill")) } }
Example 7
Source File: ProcessManager.scala From akka-cqrs with Apache License 2.0 | 5 votes |
package com.productfoundry.akka.cqrs.process import akka.actor.{ActorLogging, ReceiveTimeout} import akka.persistence.fsm.PersistentFSM import akka.persistence.fsm.PersistentFSM.FSMState import akka.productfoundry.contrib.pattern.ReceivePipeline import com.productfoundry.akka.cqrs.Entity import com.productfoundry.akka.cqrs.publish.EventPublicationInterceptor trait FsmProcessManager[S <: FSMState, D, E <: ProcessManagerEvent] extends ProcessManager with PersistentFSM[S, D, E] with ReceivePipeline with EventPublicationInterceptor { def passivationStateFunction: StateFunction = { case Event(ReceiveTimeout, _) => stop() } whenUnhandled(passivationStateFunction) }
Example 8
Source File: GracefulPassivation.scala From akka-cqrs with Apache License 2.0 | 5 votes |
package com.productfoundry.akka import akka.actor.{Actor, ReceiveTimeout} import scala.concurrent.duration._ override def unhandled(message: Any): Unit = { message match { case ReceiveTimeout => requestPassivation() case msg if msg == passivationConfig.passivationMessage => context.stop(self) case _ => super.unhandled(message) } } def requestPassivation(): Unit = { context.parent ! PassivationRequest(passivationConfig.passivationMessage) } }
Example 9
Source File: Worker.scala From akka-iot-mqtt-v2 with GNU Lesser General Public License v3.0 | 5 votes |
package akkaiot import java.util.UUID import scala.concurrent.duration._ import akka.actor.{ Props, ActorRef, Actor, ActorLogging, ReceiveTimeout, Terminated } import akka.cluster.client.ClusterClient.SendToAll import akka.actor.OneForOneStrategy import akka.actor.SupervisorStrategy.Stop import akka.actor.SupervisorStrategy.Restart import akka.actor.ActorInitializationException import akka.actor.DeathPactException object Worker { def props(clusterClient: ActorRef, workProcessorProps: Props, registerInterval: FiniteDuration = 10.seconds): Props = Props(classOf[Worker], clusterClient, workProcessorProps, registerInterval) case class WorkProcessed(result: WorkResult) } class Worker(clusterClient: ActorRef, workProcessorProps: Props, registerInterval: FiniteDuration) extends Actor with ActorLogging { import Worker._ import MasterWorkerProtocol._ val workerId = UUID.randomUUID().toString import context.dispatcher val registerTask = context.system.scheduler.schedule(0.seconds, registerInterval, clusterClient, SendToAll("/user/master/singleton", RegisterWorker(workerId))) val workProcessor = context.watch(context.actorOf(workProcessorProps, "work-processor")) var currentWorkId: Option[String] = None def workId: String = currentWorkId match { case Some(workId) => workId case None => throw new IllegalStateException("Not working") } override def supervisorStrategy = OneForOneStrategy() { case _: ActorInitializationException => Stop case _: DeathPactException => Stop case _: Exception => currentWorkId foreach { workId => sendToMaster(WorkFailed(workerId, workId)) } context.become(idle) Restart } override def postStop(): Unit = registerTask.cancel() def receive = idle def idle: Receive = { case WorkIsReady => sendToMaster(WorkerRequestsWork(workerId)) case work @ Work(workId, deviceType, deviceId, state, setting) => log.info("Worker -> Received work request from {}-{} | State {} | Setting {}", deviceType, deviceId, state, setting) currentWorkId = Some(workId) workProcessor ! work context.become(working) } def working: Receive = { case WorkProcessed(result: WorkResult) => log.info("Worker -> Processed work: {}-{} | Work Id {}", result.deviceType, result.deviceId, workId) sendToMaster(WorkIsDone(workerId, workId, result)) context.setReceiveTimeout(5.seconds) context.become(waitForWorkIsDoneAck(result)) case work: Work => log.info("Worker -> ALERT: Worker Id {} NOT AVAILABLE for Work Id {}", workerId, work.workId) } def waitForWorkIsDoneAck(result: WorkResult): Receive = { case Ack(id) if id == workId => sendToMaster(WorkerRequestsWork(workerId)) context.setReceiveTimeout(Duration.Undefined) context.become(idle) case ReceiveTimeout => log.info("Worker -> ALERT: NO ACK from cluster master, retrying ... ") sendToMaster(WorkIsDone(workerId, workId, result)) } override def unhandled(message: Any): Unit = message match { case Terminated(`workProcessor`) => context.stop(self) case WorkIsReady => case _ => super.unhandled(message) } def sendToMaster(msg: Any): Unit = { clusterClient ! SendToAll("/user/master/singleton", msg) } }
Example 10
Source File: CacheDataActor.scala From distributed-cache-on-k8s-poc with MIT License | 5 votes |
package cluster import java.util.UUID import akka.actor.SupervisorStrategy.Stop import akka.actor.{ Actor, ActorLogging, Props, ReceiveTimeout } import akka.cluster.sharding.ShardRegion import akka.cluster.sharding.ShardRegion.Passivate import cluster.CacheDataActor.Get class CacheDataActor extends Actor with ActorLogging { override def receive: Receive = { case Get(id) => sender ! s"cached data for id: $id" case ReceiveTimeout => log.info(s"sending Passivate to metadata parent: {${context.parent.path.name}} for ${self.path.name}") context.parent ! Passivate(stopMessage = Stop) case Stop => context.stop(self) log.info(s"Passivating metadata actor for ${self.path.name}") } } object CacheDataActor { final val numOfShards = 50 // Planned num of cluster nodes val extractEntityId: ShardRegion.ExtractEntityId = { case msg@Get(id) => (id.toString, msg) } val extractShardId: ShardRegion.ExtractShardId = { case Get(id) => (id.hashCode() % numOfShards).toString } case class Get(id: UUID) def props: Props = Props(new CacheDataActor()) }
Example 11
Source File: dProcessManager.scala From reactive-application-development-scala with Apache License 2.0 | 5 votes |
package com.airport import akka.actor.{ReceiveTimeout, Actor, ActorRef} import scala.concurrent.duration._ object BankTransferProcessProtocol { sealed trait BankTransferProcessMessage final case class TransferFunds( transactionId: String, fromAccount: ActorRef, toAccount: ActorRef, amount: Double) extends BankTransferProcessMessage } object BankTransferProcess { final case class FundsTransfered(transactionId: String) final case class TransferFailed(transactionId: String) } object AccountProtocol { sealed trait AccountProtocolMessage case class Withdraw(amount: Double) extends AccountProtocolMessage case class Deposit(amount: Double) extends AccountProtocolMessage final case object Acknowledgment } class BankTransferProcess extends Actor { import BankTransferProcess._ import BankTransferProcessProtocol._ import AccountProtocol._ context.setReceiveTimeout(30.minutes) override def receive = { case TransferFunds(transactionId, fromAccount, toAccount, amount) => fromAccount ! Withdraw(amount) val client = sender() context become awaitWithdrawal(transactionId, amount, toAccount, client) } def awaitWithdrawal(transactionId: String, amount: Double, toAccount: ActorRef, client: ActorRef): Receive = { case Acknowledgment => toAccount ! Deposit(amount) context become awaitDeposit(transactionId, client) case ReceiveTimeout => client ! TransferFailed(transactionId) context.stop(self) } def awaitDeposit(transactionId: String, client: ActorRef): Receive = { case Acknowledgment => client ! FundsTransfered(transactionId) context.stop(self) case ReceiveTimeout => client ! TransferFailed(transactionId) context.stop(self) } }
Example 12
Source File: FunctionInfoProviderRunner.scala From mist with Apache License 2.0 | 5 votes |
package io.hydrosphere.mist.master.jobs import akka.actor.{Actor, ActorRef, ActorSystem, Props, ReceiveTimeout} import io.hydrosphere.mist.core.CommonData import io.hydrosphere.mist.core.CommonData.RegisterJobInfoProvider import io.hydrosphere.mist.master.FunctionInfoProviderConfig import scala.concurrent.duration.{Duration, FiniteDuration} import scala.concurrent.{Future, Promise} import scala.sys.process.Process class FunctionInfoProviderRunner( runTimeout: FiniteDuration, cacheEntryTtl: FiniteDuration, masterHost: String, clusterPort: Int, sparkConf: Map[String, String] ) extends WithSparkConfArgs { def run()(implicit system: ActorSystem): Future[ActorRef] = { val refWaiter = ActorRefWaiter(runTimeout)(system) val cmd = Seq(s"${sys.env("MIST_HOME")}/bin/mist-function-info-provider", "--master", masterHost, "--cluster-port", clusterPort.toString, "--cache-entry-ttl", cacheEntryTtl.toMillis.toString) val builder = Process(cmd, None, ("SPARK_CONF", sparkConfArgs(sparkConf).mkString(" "))) builder.run(false) refWaiter.waitRef() } } trait WithSparkConfArgs { def sparkConfArgs(sparkConf: Map[String, String]): Seq[String] = { sparkConf.map { case (k, v) => s"--conf $k=$v" } .toSeq } } trait ActorRefWaiter { def waitRef(): Future[ActorRef] } object ActorRefWaiter { class IdentityActor(pr: Promise[ActorRef], initTimeout: Duration) extends Actor { override def preStart(): Unit = { context.setReceiveTimeout(initTimeout) } override def receive: Receive = { case RegisterJobInfoProvider(ref) => pr.success(ref) context stop self case ReceiveTimeout => pr.failure(new IllegalStateException("Initialization of FunctionInfoProvider failed of timeout")) context stop self } } def apply(initTimeout: Duration)(implicit system: ActorSystem): ActorRefWaiter = new ActorRefWaiter { override def waitRef(): Future[ActorRef] = { val pr = Promise[ActorRef] system.actorOf(Props(new IdentityActor(pr, initTimeout)), CommonData.FunctionInfoProviderRegisterActorName) pr.future } } } object FunctionInfoProviderRunner { def create(config: FunctionInfoProviderConfig, masterHost: String, clusterPort: Int): FunctionInfoProviderRunner = { sys.env.get("SPARK_HOME") match { case Some(_) => new FunctionInfoProviderRunner(config.runTimeout, config.cacheEntryTtl, masterHost, clusterPort, config.sparkConf) case None => throw new IllegalStateException("You should provide SPARK_HOME env variable for running mist") } } }
Example 13
Source File: RestartSupervisor.scala From mist with Apache License 2.0 | 5 votes |
package io.hydrosphere.mist.utils.akka import akka.pattern.pipe import akka.actor.{Actor, ActorLogging, ActorRef, ActorRefFactory, Props, ReceiveTimeout, SupervisorStrategy, Terminated, Timers} import io.hydrosphere.mist.utils.Logger import scala.concurrent.{Future, Promise} import scala.concurrent.duration._ class RestartSupervisor( name: String, start: () => Future[ActorRef], timeout: FiniteDuration, maxRetry: Int ) extends Actor with ActorLogging with Timers { override def receive: Receive = init import context._ import RestartSupervisor._ private def init: Receive = { case Event.Start(req) => start().map(Event.Started) pipeTo self context become await(Some(req), 0) } private def await(req: Option[Promise[ActorRef]], attempts: Int): Receive = { case Event.Started(ref) => req.foreach(_.success(self)) context watch ref context become proxy(ref) case akka.actor.Status.Failure(e) if maxRetry == attempts + 1 => req.foreach(_.failure(e)) log.error(e, "Starting child for {} failed, maxRetry reached", name) context stop self case akka.actor.Status.Failure(e) => log.error(e, "Starting child for {} failed", name) timers.startSingleTimer("timeout", Event.Timeout, timeout) context become restartTimeout(req, attempts) } private def proxy(ref: ActorRef): Receive = { case Terminated(_) => log.error(s"Reference for {} was terminated. Restarting", name) timers.startSingleTimer("timeout", Event.Timeout, timeout) context become restartTimeout(None, 0) case x => ref.forward(x) } private def restartTimeout(req: Option[Promise[ActorRef]], attempts: Int): Receive = { case Event.Timeout => start().map(Event.Started) pipeTo self context become await(req, attempts + 1) } } object RestartSupervisor { sealed trait Event object Event { final case class Start(req: Promise[ActorRef]) extends Event case object Restart extends Event final case class Started(ref: ActorRef) extends Event case object Timeout extends Event } def props( name: String, start: () => Future[ActorRef], timeout: FiniteDuration, maxRetry: Int ): Props = { Props(classOf[RestartSupervisor], name, start, timeout, maxRetry) } def wrap( name: String, start: () => Future[ActorRef], timeout: FiniteDuration, maxRetry: Int )(implicit af: ActorRefFactory): Future[ActorRef] = { val ref = af.actorOf(props(name, start, timeout, maxRetry)) val promise = Promise[ActorRef] ref ! Event.Start(promise) promise.future } def wrap( name: String, maxRetry: Int, start: () => Future[ActorRef] )(implicit af: ActorRefFactory): Future[ActorRef] = wrap(name, start, 5 seconds, maxRetry)(af) }
Example 14
Source File: FactorialFrontend.scala From fusion-data with Apache License 2.0 | 5 votes |
package sample.cluster.factorial import akka.actor.{ Actor, ActorLogging, ActorSystem, Props, ReceiveTimeout } import akka.cluster.Cluster import akka.routing.FromConfig import com.typesafe.config.ConfigFactory import scala.concurrent.Await import scala.concurrent.duration._ import scala.util.Try class FactorialFrontend(upToN: Int, repeat: Boolean) extends Actor with ActorLogging { val backend = context.actorOf(FromConfig.props(), name = "factorialBackendRouter") override def preStart(): Unit = { sendJobs() if (repeat) { context.setReceiveTimeout(10.seconds) } } def receive = { case (n: Int, factorial: BigInt) => log.info("{}! = {}", n, factorial) if (n == upToN) { if (repeat) sendJobs() else context.stop(self) } case ReceiveTimeout => log.info("Timeout") sendJobs() } def sendJobs(): Unit = // log.info("Starting batch of factorials up to [{}]", upToN) 1 to upToN foreach { backend ! _ } } object FactorialFrontend { def main(args: Array[String]): Unit = { val upToN = 200 val config = ConfigFactory.parseString("akka.cluster.roles = [frontend]").withFallback(ConfigFactory.load("factorial")) val system = ActorSystem("ClusterSystem", config) system.log.info("Factorials will start when 2 backend members in the cluster.") Cluster(system) registerOnMemberUp { system.actorOf(Props(classOf[FactorialFrontend], upToN, false), name = "factorialFrontend") } Cluster(system).registerOnMemberRemoved { // exit JVM when ActorSystem has been terminated system.registerOnTermination(System.exit(0)) // shut down ActorSystem system.terminate() // In case ActorSystem shutdown takes longer than 10 seconds, // exit the JVM forcefully anyway. // We must spawn a separate thread to not block current thread, // since that would have blocked the shutdown of the ActorSystem. new Thread { override def run(): Unit = if (Try(Await.ready(system.whenTerminated, 10.seconds)).isFailure) System.exit(-1) }.start() } } }
Example 15
Source File: StatsService.scala From fusion-data with Apache License 2.0 | 5 votes |
package sample.cluster.stats import akka.actor.{ Actor, ActorRef, Props, ReceiveTimeout } import akka.routing.ConsistentHashingRouter.ConsistentHashableEnvelope import akka.routing.FromConfig import scala.concurrent.duration._ //#service class StatsService extends Actor { // This router is used both with lookup and deploy of routees. If you // have a router with only lookup of routees you can use Props.empty // instead of Props[StatsWorker.class]. val workerRouter = context.actorOf(FromConfig.props(Props[StatsWorker]), name = "workerRouter") def receive = { case StatsJob(text) if text != "" => val words = text.split(" ") val replyTo = sender() // important to not close over sender() // create actor that collects replies from workers val aggregator = context.actorOf(Props(classOf[StatsAggregator], words.size, replyTo)) words foreach { word => workerRouter.tell(ConsistentHashableEnvelope(word, word), aggregator) } } } class StatsAggregator(expectedResults: Int, replyTo: ActorRef) extends Actor { var results = IndexedSeq.empty[Int] context.setReceiveTimeout(3.seconds) def receive = { case wordCount: Int => results = results :+ wordCount if (results.size == expectedResults) { val meanWordLength = results.sum.toDouble / results.size replyTo ! StatsResult(meanWordLength) context.stop(self) } case ReceiveTimeout => replyTo ! JobFailed("Service unavailable, try again later") context.stop(self) } } //#service
Example 16
Source File: Sender.scala From fusion-data with Apache License 2.0 | 5 votes |
package sample.remote.benchmark import akka.actor.{ Actor, ActorIdentity, ActorRef, ActorSystem, Identify, Props, ReceiveTimeout, Terminated } import com.typesafe.config.ConfigFactory import scala.concurrent.duration._ class Sender(path: String, totalMessages: Int, burstSize: Int, payloadSize: Int) extends Actor { import Sender._ val payload: Array[Byte] = Vector.fill(payloadSize)("a").mkString.getBytes println(s"payload bytes: ${payload.length}") var startTime = 0L var maxRoundTripMillis = 0L context.setReceiveTimeout(3.seconds) // 设置Actor自身接收消息超时时长 sendIdentifyRequest() // 发请求确认远程actor的路径是否有效。 override def receive: Receive = identifying def identifying: Receive = { case ActorIdentity(`path`, Some(actor)) => context.watch(actor) context.become(active(actor)) context.setReceiveTimeout(Duration.Undefined) // 重置超时时间 self ! Warmup case ActorIdentity(`path`, None) => println(s"远程actor无效:$path") case ReceiveTimeout => sendIdentifyRequest() // 超时,再次确认远程actor是否有效 } def active(actor: ActorRef): Receive = { case Warmup => // 热身,不计入统计 sendBatch(actor, burstSize) actor ! Start case Start => println(s"启动基准测试一共 $totalMessages 消息,分帧大小 $burstSize,有效负载 $payloadSize") startTime = System.nanoTime() val remaining = sendBatch(actor, totalMessages) if (remaining == 0) actor ! Done else actor ! Continue(remaining, startTime, startTime, burstSize) case c @ Continue(remaining, t0, t1, n) => val now = System.nanoTime() val duration = (now - t0).nanos.toMillis // 从发出 Continue 指令到收到指令回复花费的时间 val roundTripMillis = (now - t1).nanos.toMillis maxRoundTripMillis = math.max(maxRoundTripMillis, roundTripMillis) if (duration >= 500) { // 以500ms为间隔作统计 val throughtput = (n * 1000.0 / duration).toInt println(s"花费 ${duration}ms 发送了 $n 条消息,吞吐量 ${throughtput}msg/s,") } val nextRemaining = sendBatch(actor, remaining) if (nextRemaining == 0) actor ! Done else if (duration >= 500) // 一个批次的数量已发完 actor ! Continue(nextRemaining, now, now, burstSize) else // 间隔时间不足500ms,更新 剩余数量、(分帧)起始时间、分帧发送数量 actor ! c.copy(remaining = nextRemaining, burstStartTime = now, n = n + burstSize) case Done => val took = (System.nanoTime - startTime).nanos.toMillis val throughtput = (totalMessages * 1000.0 / took).toInt println( s"一共花费 ${took}ms 发送了 ${totalMessages}消息, 吞吐量 ${throughtput}msg/s, " + s"最大往返时间 ${maxRoundTripMillis}ms, 分帧数据大小 $burstSize, " + s"有效负载 $payloadSize") actor ! Shutdown case Terminated(`actor`) => println("Receiver terminated") context.system.terminate() } case class Continue(remaining: Int, startTime: Long, burstStartTime: Long, n: Int) extends Echo def main(args: Array[String]): Unit = { val system = ActorSystem("Sys", ConfigFactory.load("calculator")) val remoteHostPort = if (args.nonEmpty) args(0) else "127.0.0.1:2553" val remotePath = s"akka.tcp://Sys@$remoteHostPort/user/rcv" val totalMessages = if (args.length >= 2) args(1).toInt else 500000 val burstSize = if (args.length >= 3) args(2).toInt else 5000 val payloadSize = if (args.length >= 4) args(3).toInt else 100 system.actorOf(Sender.props(remotePath, totalMessages, burstSize, payloadSize), "snd") } def props(path: String, totalMessages: Int, burstSize: Int, payloadSize: Int) = Props(new Sender(path, totalMessages, burstSize, payloadSize)) }