101 lines
3 KiB
Scala
101 lines
3 KiB
Scala
package scala.docs.cluster
|
|
|
|
import scala.concurrent.duration._
|
|
import com.typesafe.config.ConfigFactory
|
|
import akka.actor.Actor
|
|
import akka.actor.ActorLogging
|
|
import akka.actor.ActorSystem
|
|
import akka.actor.Props
|
|
import akka.cluster.Cluster
|
|
import akka.routing.FromConfig
|
|
import akka.actor.ReceiveTimeout
|
|
import scala.util.Try
|
|
import scala.concurrent.Await
|
|
|
|
//#frontend
|
|
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) =>
|
|
if (n == upToN) {
|
|
log.debug("{}! = {}", n, factorial)
|
|
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 ! _ }
|
|
}
|
|
}
|
|
//#frontend
|
|
|
|
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.")
|
|
//#registerOnUp
|
|
Cluster(system) registerOnMemberUp {
|
|
system.actorOf(
|
|
Props(classOf[FactorialFrontend], upToN, true),
|
|
name = "factorialFrontend")
|
|
}
|
|
//#registerOnUp
|
|
|
|
}
|
|
}
|
|
|
|
// not used, only for documentation
|
|
abstract class FactorialFrontend2 extends Actor {
|
|
//#router-lookup-in-code
|
|
import akka.cluster.routing.ClusterRouterGroup
|
|
import akka.cluster.routing.ClusterRouterGroupSettings
|
|
import akka.cluster.metrics.AdaptiveLoadBalancingGroup
|
|
import akka.cluster.metrics.HeapMetricsSelector
|
|
|
|
val backend = context.actorOf(
|
|
ClusterRouterGroup(
|
|
AdaptiveLoadBalancingGroup(HeapMetricsSelector),
|
|
ClusterRouterGroupSettings(
|
|
totalInstances = 100, routeesPaths = List("/user/factorialBackend"),
|
|
allowLocalRoutees = true, useRole = Some("backend"))).props(),
|
|
name = "factorialBackendRouter2")
|
|
//#router-lookup-in-code
|
|
}
|
|
|
|
// not used, only for documentation
|
|
abstract class FactorialFrontend3 extends Actor {
|
|
//#router-deploy-in-code
|
|
import akka.cluster.routing.ClusterRouterPool
|
|
import akka.cluster.routing.ClusterRouterPoolSettings
|
|
import akka.cluster.metrics.AdaptiveLoadBalancingPool
|
|
import akka.cluster.metrics.SystemLoadAverageMetricsSelector
|
|
|
|
val backend = context.actorOf(
|
|
ClusterRouterPool(AdaptiveLoadBalancingPool(
|
|
SystemLoadAverageMetricsSelector), ClusterRouterPoolSettings(
|
|
totalInstances = 100, maxInstancesPerNode = 3,
|
|
allowLocalRoutees = false, useRole = Some("backend"))).props(Props[FactorialBackend]),
|
|
name = "factorialBackendRouter3")
|
|
//#router-deploy-in-code
|
|
}
|