!act,rem,clu #3549 Simplify and enhance routers
* Separate routing logic, to be usable stand alone, e.g. in actors * Simplify RouterConfig, only a factory * Move reading of config from Deployer to the RouterConfig * Distiction between Pool and Group router types * Remove usage of actorFor, use ActorSelection * Management messages to add and remove routees * Simplify the internals of RoutedActorCell & co * Move resize specific code to separate RoutedActorCell subclass * Change resizer api to only return capacity change * Resizer only allowed together with Pool * Re-implement all routers, and keep old api during deprecation phase * Replace ClusterRouterConfig, deprecation * Rewrite documentation * Migration guide * Also includes related ticket: +act #3087 Create nicer Props factories for RouterConfig
This commit is contained in:
parent
81ca6fe8c8
commit
ebadd567b2
104 changed files with 9671 additions and 5006 deletions
142
akka-actor/src/main/scala/akka/routing/Random.scala
Normal file
142
akka-actor/src/main/scala/akka/routing/Random.scala
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
/**
|
||||
* Copyright (C) 2009-2013 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
package akka.routing
|
||||
|
||||
import scala.collection.immutable
|
||||
import scala.concurrent.forkjoin.ThreadLocalRandom
|
||||
import akka.actor.ActorContext
|
||||
import akka.actor.Props
|
||||
import akka.dispatch.Dispatchers
|
||||
import com.typesafe.config.Config
|
||||
import akka.actor.SupervisorStrategy
|
||||
import akka.japi.Util.immutableSeq
|
||||
import akka.actor.ActorSystem
|
||||
|
||||
object RandomRoutingLogic {
|
||||
def apply(): RandomRoutingLogic = new RandomRoutingLogic
|
||||
}
|
||||
|
||||
/**
|
||||
* Randomly selects one of the target routees to send a message to
|
||||
*/
|
||||
@SerialVersionUID(1L)
|
||||
final class RandomRoutingLogic extends RoutingLogic {
|
||||
override def select(message: Any, routees: immutable.IndexedSeq[Routee]): Routee =
|
||||
if (routees.isEmpty) NoRoutee
|
||||
else routees(ThreadLocalRandom.current.nextInt(routees.size))
|
||||
}
|
||||
|
||||
/**
|
||||
* A router pool that randomly selects one of the target routees to send a message to.
|
||||
*
|
||||
* The configuration parameter trumps the constructor arguments. This means that
|
||||
* if you provide `nrOfInstances` during instantiation they will be ignored if
|
||||
* the router is defined in the configuration file for the actor being used.
|
||||
*
|
||||
* <h1>Supervision Setup</h1>
|
||||
*
|
||||
* Any routees that are created by a router will be created as the router's children.
|
||||
* The router is therefore also the children's supervisor.
|
||||
*
|
||||
* The supervision strategy of the router actor can be configured with
|
||||
* [[#withSupervisorStrategy]]. If no strategy is provided, routers default to
|
||||
* a strategy of “always escalate”. This means that errors are passed up to the
|
||||
* router's supervisor for handling.
|
||||
*
|
||||
* The router's supervisor will treat the error as an error with the router itself.
|
||||
* Therefore a directive to stop or restart will cause the router itself to stop or
|
||||
* restart. The router, in turn, will cause its children to stop and restart.
|
||||
*
|
||||
* @param nrOfInstances initial number of routees in the pool
|
||||
*
|
||||
* @param resizer optional resizer that dynamically adjust the pool size
|
||||
*
|
||||
* @param supervisorStrategy strategy for supervising the routees, see 'Supervision Setup'
|
||||
*
|
||||
* @param routerDispatcher dispatcher to use for the router head actor, which handles
|
||||
* supervision, death watch and router management messages
|
||||
*/
|
||||
@SerialVersionUID(1L)
|
||||
final case class RandomPool(
|
||||
override val nrOfInstances: Int, override val resizer: Option[Resizer] = None,
|
||||
override val supervisorStrategy: SupervisorStrategy = Pool.defaultSupervisorStrategy,
|
||||
override val routerDispatcher: String = Dispatchers.DefaultDispatcherId)
|
||||
extends Pool with PoolOverrideUnsetConfig[RandomPool] {
|
||||
|
||||
def this(config: Config) =
|
||||
this(
|
||||
nrOfInstances = config.getInt("nr-of-instances"),
|
||||
resizer = DefaultResizer.fromConfig(config))
|
||||
|
||||
/**
|
||||
* Java API
|
||||
* @param nr initial number of routees in the pool
|
||||
*/
|
||||
def this(nr: Int) = this(nrOfInstances = nr)
|
||||
|
||||
override def createRouter(system: ActorSystem): Router = new Router(RandomRoutingLogic())
|
||||
|
||||
/**
|
||||
* Setting the supervisor strategy to be used for the “head” Router actor.
|
||||
*/
|
||||
def withSupervisorStrategy(strategy: SupervisorStrategy): RandomPool = copy(supervisorStrategy = strategy)
|
||||
|
||||
/**
|
||||
* Setting the resizer to be used.
|
||||
*/
|
||||
def withResizer(resizer: Resizer): RandomPool = copy(resizer = Some(resizer))
|
||||
|
||||
/**
|
||||
* Setting the dispatcher to be used for the router head actor, which handles
|
||||
* supervision, death watch and router management messages.
|
||||
*/
|
||||
def withDispatcher(dispatcherId: String): RandomPool = copy(routerDispatcher = dispatcherId)
|
||||
|
||||
/**
|
||||
* Uses the resizer and/or the supervisor strategy of the given Routerconfig
|
||||
* if this RouterConfig doesn't have one, i.e. the resizer defined in code is used if
|
||||
* resizer was not defined in config.
|
||||
*/
|
||||
override def withFallback(other: RouterConfig): RouterConfig = this.overrideUnsetConfig(other)
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A router group that randomly selects one of the target routees to send a message to.
|
||||
*
|
||||
* The configuration parameter trumps the constructor arguments. This means that
|
||||
* if you provide `paths` during instantiation they will be ignored if
|
||||
* the router is defined in the configuration file for the actor being used.
|
||||
*
|
||||
* @param paths string representation of the actor paths of the routees, messages are
|
||||
* sent with [[akka.actor.ActorSelection]] to these paths
|
||||
*
|
||||
* @param routerDispatcher dispatcher to use for the router head actor, which handles
|
||||
* router management messages
|
||||
*/
|
||||
@SerialVersionUID(1L)
|
||||
final case class RandomGroup(
|
||||
override val paths: immutable.Iterable[String],
|
||||
override val routerDispatcher: String = Dispatchers.DefaultDispatcherId)
|
||||
extends Group {
|
||||
|
||||
def this(config: Config) =
|
||||
this(paths = immutableSeq(config.getStringList("routees.paths")))
|
||||
|
||||
/**
|
||||
* Java API
|
||||
* @param routeePaths string representation of the actor paths of the routees, messages are
|
||||
* sent with [[akka.actor.ActorSelection]] to these paths
|
||||
*/
|
||||
def this(routeePaths: java.lang.Iterable[String]) = this(paths = immutableSeq(routeePaths))
|
||||
|
||||
override def createRouter(system: ActorSystem): Router = new Router(RandomRoutingLogic())
|
||||
|
||||
/**
|
||||
* Setting the dispatcher to be used for the router head actor, which handles
|
||||
* router management messages
|
||||
*/
|
||||
def withDispatcher(dispatcherId: String): RandomGroup = copy(routerDispatcher = dispatcherId)
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue