Updates based on feedback - use of abstract member variables specific to the router type. See #1529

This commit is contained in:
Henrik Engstrom 2011-12-21 10:03:26 +01:00
parent 0dc161c800
commit dac0beb01b
4 changed files with 38 additions and 28 deletions

View file

@ -373,12 +373,12 @@ class RoutingSpec extends AkkaSpec with DefaultTimeout with ImplicitSender {
"custom router" must { "custom router" must {
"be started when constructed" in { "be started when constructed" in {
val routedActor = system.actorOf(Props[TestActor].withRouter(VoteCountRouter())) val routedActor = system.actorOf(Props[TestActor].withRouter(new VoteCountRouter))
routedActor.isTerminated must be(false) routedActor.isTerminated must be(false)
} }
"count votes as intended - not as in Florida" in { "count votes as intended - not as in Florida" in {
val routedActor = system.actorOf(Props[TestActor].withRouter(VoteCountRouter())) val routedActor = system.actorOf(Props[TestActor].withRouter(new VoteCountRouter))
routedActor ! DemocratVote routedActor ! DemocratVote
routedActor ! DemocratVote routedActor ! DemocratVote
routedActor ! RepublicanVote routedActor ! RepublicanVote
@ -422,11 +422,7 @@ class RoutingSpec extends AkkaSpec with DefaultTimeout with ImplicitSender {
//#crActors //#crActors
//#crRouter //#crRouter
case class VoteCountRouter( class VoteCountRouter extends RouterConfig {
nrOfInstances: Int = 0,
routees: Iterable[String] = Nil,
within: Duration = Duration.Zero)
extends RouterConfig {
//#crRoute //#crRoute
def createRoute(props: Props, def createRoute(props: Props,

View file

@ -79,12 +79,6 @@ private[akka] class RoutedActorRef(_system: ActorSystemImpl, _props: Props, _sup
*/ */
trait RouterConfig { trait RouterConfig {
def nrOfInstances: Int
def routees: Iterable[String]
def within: Duration
def createRoute(props: Props, actorContext: ActorContext, ref: RoutedActorRef): Route def createRoute(props: Props, actorContext: ActorContext, ref: RoutedActorRef): Route
def createActor(): Router = new Router {} def createActor(): Router = new Router {}
@ -173,9 +167,8 @@ case class Destination(sender: ActorRef, recipient: ActorRef)
* Oxymoron style. * Oxymoron style.
*/ */
case object NoRouter extends RouterConfig { case object NoRouter extends RouterConfig {
def nrOfInstances = 0 def nrOfInstances: Int = 0
def routees = Nil def routees: Iterable[String] = Nil
def within = Duration.Zero
def createRoute(props: Props, actorContext: ActorContext, ref: RoutedActorRef): Route = null def createRoute(props: Props, actorContext: ActorContext, ref: RoutedActorRef): Route = null
} }
@ -193,7 +186,7 @@ object RoundRobinRouter {
* if you provide either 'nrOfInstances' or 'routees' to during instantiation they will * if you provide either 'nrOfInstances' or 'routees' to during instantiation they will
* be ignored if the 'nrOfInstances' is defined in the configuration file for the actor being used. * be ignored if the 'nrOfInstances' is defined in the configuration file for the actor being used.
*/ */
case class RoundRobinRouter(nrOfInstances: Int = 0, routees: Iterable[String] = Nil, within: Duration = Duration.Zero) extends RouterConfig with RoundRobinLike { case class RoundRobinRouter(nrOfInstances: Int = 0, routees: Iterable[String] = Nil) extends RouterConfig with RoundRobinLike {
/** /**
* Constructor that sets nrOfInstances to be created. * Constructor that sets nrOfInstances to be created.
@ -213,6 +206,11 @@ case class RoundRobinRouter(nrOfInstances: Int = 0, routees: Iterable[String] =
} }
trait RoundRobinLike { this: RouterConfig trait RoundRobinLike { this: RouterConfig
val nrOfInstances: Int
val routees: Iterable[String]
def createRoute(props: Props, context: ActorContext, ref: RoutedActorRef): Route = { def createRoute(props: Props, context: ActorContext, ref: RoutedActorRef): Route = {
createAndRegisterRoutees(props, context, nrOfInstances, routees) createAndRegisterRoutees(props, context, nrOfInstances, routees)
@ -246,7 +244,7 @@ object RandomRouter {
* if you provide either 'nrOfInstances' or 'routees' to during instantiation they will * if you provide either 'nrOfInstances' or 'routees' to during instantiation they will
* be ignored if the 'nrOfInstances' is defined in the configuration file for the actor being used. * be ignored if the 'nrOfInstances' is defined in the configuration file for the actor being used.
*/ */
case class RandomRouter(nrOfInstances: Int = 0, routees: Iterable[String] = Nil, within: Duration = Duration.Zero) extends RouterConfig with RandomLike { case class RandomRouter(nrOfInstances: Int = 0, routees: Iterable[String] = Nil) extends RouterConfig with RandomLike {
/** /**
* Constructor that sets nrOfInstances to be created. * Constructor that sets nrOfInstances to be created.
@ -269,6 +267,10 @@ trait RandomLike { this: RouterConfig ⇒
import java.security.SecureRandom import java.security.SecureRandom
val nrOfInstances: Int
val routees: Iterable[String]
private val random = new ThreadLocal[SecureRandom] { private val random = new ThreadLocal[SecureRandom] {
override def initialValue = SecureRandom.getInstance("SHA1PRNG") override def initialValue = SecureRandom.getInstance("SHA1PRNG")
} }
@ -304,7 +306,7 @@ object BroadcastRouter {
* if you provide either 'nrOfInstances' or 'routees' to during instantiation they will * if you provide either 'nrOfInstances' or 'routees' to during instantiation they will
* be ignored if the 'nrOfInstances' is defined in the configuration file for the actor being used. * be ignored if the 'nrOfInstances' is defined in the configuration file for the actor being used.
*/ */
case class BroadcastRouter(nrOfInstances: Int = 0, routees: Iterable[String] = Nil, within: Duration = Duration.Zero) extends RouterConfig with BroadcastLike { case class BroadcastRouter(nrOfInstances: Int = 0, routees: Iterable[String] = Nil) extends RouterConfig with BroadcastLike {
/** /**
* Constructor that sets nrOfInstances to be created. * Constructor that sets nrOfInstances to be created.
@ -324,6 +326,11 @@ case class BroadcastRouter(nrOfInstances: Int = 0, routees: Iterable[String] = N
} }
trait BroadcastLike { this: RouterConfig trait BroadcastLike { this: RouterConfig
val nrOfInstances: Int
val routees: Iterable[String]
def createRoute(props: Props, context: ActorContext, ref: RoutedActorRef): Route = { def createRoute(props: Props, context: ActorContext, ref: RoutedActorRef): Route = {
createAndRegisterRoutees(props, context, nrOfInstances, routees) createAndRegisterRoutees(props, context, nrOfInstances, routees)
@ -371,6 +378,13 @@ case class ScatterGatherFirstCompletedRouter(nrOfInstances: Int = 0, routees: It
} }
trait ScatterGatherFirstCompletedLike { this: RouterConfig trait ScatterGatherFirstCompletedLike { this: RouterConfig
val nrOfInstances: Int
val routees: Iterable[String]
val within: Duration
def createRoute(props: Props, context: ActorContext, ref: RoutedActorRef): Route = { def createRoute(props: Props, context: ActorContext, ref: RoutedActorRef): Route = {
createAndRegisterRoutees(props, context, nrOfInstances, routees) createAndRegisterRoutees(props, context, nrOfInstances, routees)

View file

@ -26,9 +26,9 @@ class RemoteDeployer(_settings: ActorSystem.Settings) extends Deployer(_settings
if (nodes.isEmpty || deploy.routing == NoRouter) d if (nodes.isEmpty || deploy.routing == NoRouter) d
else { else {
val r = deploy.routing match { val r = deploy.routing match {
case RoundRobinRouter(x, _, w) RemoteRoundRobinRouter(x, nodes, w) case RoundRobinRouter(x, _) RemoteRoundRobinRouter(x, nodes)
case RandomRouter(x, _, w) RemoteRandomRouter(x, nodes, w) case RandomRouter(x, _) RemoteRandomRouter(x, nodes)
case BroadcastRouter(x, _, w) RemoteBroadcastRouter(x, nodes, w) case BroadcastRouter(x, _) RemoteBroadcastRouter(x, nodes)
case ScatterGatherFirstCompletedRouter(x, _, w) RemoteScatterGatherFirstCompletedRouter(x, nodes, w) case ScatterGatherFirstCompletedRouter(x, _, w) RemoteScatterGatherFirstCompletedRouter(x, nodes, w)
} }
Some(deploy.copy(routing = r)) Some(deploy.copy(routing = r))

View file

@ -39,13 +39,13 @@ trait RemoteRouterConfig extends RouterConfig {
* if you provide either 'nrOfInstances' or 'routees' to during instantiation they will * if you provide either 'nrOfInstances' or 'routees' to during instantiation they will
* be ignored if the 'nrOfInstances' is defined in the configuration file for the actor being used. * be ignored if the 'nrOfInstances' is defined in the configuration file for the actor being used.
*/ */
case class RemoteRoundRobinRouter(nrOfInstances: Int, routees: Iterable[String], within: Duration) extends RemoteRouterConfig with RoundRobinLike { case class RemoteRoundRobinRouter(nrOfInstances: Int, routees: Iterable[String]) extends RemoteRouterConfig with RoundRobinLike {
/** /**
* Constructor that sets the routees to be used. * Constructor that sets the routees to be used.
* Java API * Java API
*/ */
def this(n: Int, t: java.util.Collection[String], w: Duration) = this(n, t.asScala, w) def this(n: Int, t: java.util.Collection[String]) = this(n, t.asScala)
} }
/** /**
@ -59,13 +59,13 @@ case class RemoteRoundRobinRouter(nrOfInstances: Int, routees: Iterable[String],
* if you provide either 'nrOfInstances' or 'routees' to during instantiation they will * if you provide either 'nrOfInstances' or 'routees' to during instantiation they will
* be ignored if the 'nrOfInstances' is defined in the configuration file for the actor being used. * be ignored if the 'nrOfInstances' is defined in the configuration file for the actor being used.
*/ */
case class RemoteRandomRouter(nrOfInstances: Int, routees: Iterable[String], within: Duration) extends RemoteRouterConfig with RandomLike { case class RemoteRandomRouter(nrOfInstances: Int, routees: Iterable[String]) extends RemoteRouterConfig with RandomLike {
/** /**
* Constructor that sets the routees to be used. * Constructor that sets the routees to be used.
* Java API * Java API
*/ */
def this(n: Int, t: java.util.Collection[String], w: Duration) = this(n, t.asScala, w) def this(n: Int, t: java.util.Collection[String]) = this(n, t.asScala)
} }
/** /**
@ -79,13 +79,13 @@ case class RemoteRandomRouter(nrOfInstances: Int, routees: Iterable[String], wit
* if you provide either 'nrOfInstances' or 'routees' to during instantiation they will * if you provide either 'nrOfInstances' or 'routees' to during instantiation they will
* be ignored if the 'nrOfInstances' is defined in the configuration file for the actor being used. * be ignored if the 'nrOfInstances' is defined in the configuration file for the actor being used.
*/ */
case class RemoteBroadcastRouter(nrOfInstances: Int, routees: Iterable[String], within: Duration) extends RemoteRouterConfig with BroadcastLike { case class RemoteBroadcastRouter(nrOfInstances: Int, routees: Iterable[String]) extends RemoteRouterConfig with BroadcastLike {
/** /**
* Constructor that sets the routees to be used. * Constructor that sets the routees to be used.
* Java API * Java API
*/ */
def this(n: Int, t: java.util.Collection[String], w: Duration) = this(n, t.asScala, w) def this(n: Int, t: java.util.Collection[String]) = this(n, t.asScala)
} }
/** /**