2011-04-27 00:40:20 +02:00
|
|
|
/**
|
2011-07-14 16:03:08 +02:00
|
|
|
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com>
|
2011-04-27 00:40:20 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
package akka.actor
|
|
|
|
|
|
|
|
|
|
import collection.immutable.Seq
|
2011-10-29 19:10:58 +02:00
|
|
|
import akka.event.Logging
|
2011-11-10 20:08:00 +01:00
|
|
|
import akka.AkkaException
|
2011-11-15 11:34:39 +01:00
|
|
|
import akka.config.ConfigurationException
|
2011-10-07 15:42:55 +02:00
|
|
|
import akka.util.Duration
|
2011-11-14 18:18:08 +01:00
|
|
|
import akka.event.EventStream
|
2011-12-09 20:19:59 +01:00
|
|
|
import com.typesafe.config._
|
2011-12-12 23:31:15 +01:00
|
|
|
import akka.routing._
|
2011-12-20 19:57:42 +01:00
|
|
|
import java.util.concurrent.{ TimeUnit, ConcurrentHashMap }
|
2011-12-12 23:31:15 +01:00
|
|
|
|
|
|
|
|
case class Deploy(path: String, config: Config, recipe: Option[ActorRecipe] = None, routing: RouterConfig = NoRouter, scope: Scope = LocalScope)
|
|
|
|
|
|
|
|
|
|
case class ActorRecipe(implementationClass: Class[_ <: Actor]) //TODO Add ActorConfiguration here
|
|
|
|
|
|
|
|
|
|
trait Scope
|
|
|
|
|
case class LocalScope() extends Scope
|
|
|
|
|
case object LocalScope extends Scope
|
2011-04-27 00:40:20 +02:00
|
|
|
|
|
|
|
|
/**
|
2011-11-08 16:49:50 +01:00
|
|
|
* Deployer maps actor paths to actor deployments.
|
2011-04-27 00:40:20 +02:00
|
|
|
*
|
|
|
|
|
* @author <a href="http://jonasboner.com">Jonas Bonér</a>
|
|
|
|
|
*/
|
2011-12-09 20:19:59 +01:00
|
|
|
class Deployer(val settings: ActorSystem.Settings) {
|
2011-05-03 21:04:45 +02:00
|
|
|
|
2011-12-09 20:19:59 +01:00
|
|
|
import scala.collection.JavaConverters._
|
2011-05-03 21:04:45 +02:00
|
|
|
|
2011-12-09 20:19:59 +01:00
|
|
|
private val deployments = new ConcurrentHashMap[String, Deploy]
|
|
|
|
|
private val config = settings.config.getConfig("akka.actor.deployment")
|
|
|
|
|
protected val default = config.getConfig("default")
|
|
|
|
|
config.root.asScala flatMap {
|
|
|
|
|
case ("default", _) ⇒ None
|
|
|
|
|
case (key, value: ConfigObject) ⇒ parseConfig(key, value.toConfig)
|
|
|
|
|
case _ ⇒ None
|
|
|
|
|
} foreach deploy
|
2011-05-03 21:04:45 +02:00
|
|
|
|
2011-12-09 20:19:59 +01:00
|
|
|
def lookup(path: String): Option[Deploy] = Option(deployments.get(path))
|
2011-11-15 11:34:39 +01:00
|
|
|
|
2011-12-09 20:19:59 +01:00
|
|
|
def deploy(d: Deploy): Unit = deployments.put(d.path, d)
|
2011-05-03 21:04:45 +02:00
|
|
|
|
2011-12-09 20:19:59 +01:00
|
|
|
protected def parseConfig(key: String, config: Config): Option[Deploy] = {
|
2011-11-19 19:55:44 +01:00
|
|
|
import akka.util.ReflectiveAccess.getClassFor
|
2011-04-27 00:40:20 +02:00
|
|
|
|
2011-12-09 20:19:59 +01:00
|
|
|
val deployment = config.withFallback(default)
|
2011-07-26 17:12:00 +02:00
|
|
|
|
2011-12-17 16:33:29 +01:00
|
|
|
val routees = deployment.getStringList("routees.paths").asScala.toSeq
|
2011-12-12 23:31:15 +01:00
|
|
|
|
|
|
|
|
val nrOfInstances = deployment.getInt("nr-of-instances")
|
|
|
|
|
|
2011-12-20 19:57:42 +01:00
|
|
|
val within = Duration(deployment.getMilliseconds("within"), TimeUnit.MILLISECONDS)
|
|
|
|
|
|
2011-12-12 23:31:15 +01:00
|
|
|
val router: RouterConfig = deployment.getString("router") match {
|
2011-12-15 21:59:30 +01:00
|
|
|
case "from-code" ⇒ NoRouter
|
2011-12-17 16:33:29 +01:00
|
|
|
case "round-robin" ⇒ RoundRobinRouter(nrOfInstances, routees)
|
|
|
|
|
case "random" ⇒ RandomRouter(nrOfInstances, routees)
|
2011-12-20 19:57:42 +01:00
|
|
|
case "scatter-gather" ⇒ ScatterGatherFirstCompletedRouter(nrOfInstances, routees, within)
|
2011-12-17 16:33:29 +01:00
|
|
|
case "broadcast" ⇒ BroadcastRouter(nrOfInstances, routees)
|
2011-12-12 23:31:15 +01:00
|
|
|
case x ⇒ throw new ConfigurationException("unknown router type " + x + " for path " + key)
|
2011-11-19 19:55:44 +01:00
|
|
|
}
|
2011-09-28 14:50:09 +02:00
|
|
|
|
2011-11-19 19:55:44 +01:00
|
|
|
val recipe: Option[ActorRecipe] =
|
2011-12-09 20:19:59 +01:00
|
|
|
deployment.getString("create-as.class") match {
|
2011-11-19 19:55:44 +01:00
|
|
|
case "" ⇒ None
|
|
|
|
|
case impl ⇒
|
|
|
|
|
val implementationClass = getClassFor[Actor](impl).fold(e ⇒ throw new ConfigurationException(
|
2011-12-09 20:19:59 +01:00
|
|
|
"Config option [akka.actor.deployment." + key + ".create-as.class] load failed", e), identity)
|
2011-11-19 19:55:44 +01:00
|
|
|
Some(ActorRecipe(implementationClass))
|
|
|
|
|
}
|
|
|
|
|
|
2011-12-12 23:31:15 +01:00
|
|
|
Some(Deploy(key, deployment, recipe, router, LocalScope))
|
2011-04-27 00:40:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|