only create the routees once they can be looked-up, see #3406
- move the creation of the RoutedActorCell’s route into ActorCell.start(); it used to be done in the constructor - this requires “val route” to turn into a volatile private var Thanks to Patrik for finding it!
This commit is contained in:
parent
9c89f170d2
commit
0af123aa6d
3 changed files with 65 additions and 4 deletions
|
|
@ -0,0 +1,51 @@
|
||||||
|
/**
|
||||||
|
* Copyright (C) 2009-2013 Typesafe Inc. <http://www.typesafe.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
package akka.routing
|
||||||
|
|
||||||
|
import akka.testkit.AkkaSpec
|
||||||
|
import akka.actor.Props
|
||||||
|
import akka.actor.Actor
|
||||||
|
import akka.actor.ActorRef
|
||||||
|
import akka.actor.LocalActorRef
|
||||||
|
import scala.concurrent.duration._
|
||||||
|
|
||||||
|
class RouteeCreationSpec extends AkkaSpec {
|
||||||
|
|
||||||
|
"Creating Routees" must {
|
||||||
|
|
||||||
|
"result in visible routees" in {
|
||||||
|
val N = 100
|
||||||
|
system.actorOf(Props(new Actor {
|
||||||
|
testActor ! system.actorFor(self.path)
|
||||||
|
def receive = Actor.emptyBehavior
|
||||||
|
}).withRouter(RoundRobinRouter(N)))
|
||||||
|
for (i ← 1 to N) {
|
||||||
|
expectMsgType[ActorRef] match {
|
||||||
|
case _: LocalActorRef ⇒ // fine
|
||||||
|
case x ⇒ fail(s"routee $i was a ${x.getClass}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"allow sending to context.parent" in {
|
||||||
|
val N = 100
|
||||||
|
system.actorOf(Props(new Actor {
|
||||||
|
context.parent ! "one"
|
||||||
|
def receive = {
|
||||||
|
case "one" ⇒ testActor forward "two"
|
||||||
|
}
|
||||||
|
}).withRouter(RoundRobinRouter(N)))
|
||||||
|
val gotit = receiveWhile(messages = N) {
|
||||||
|
case "two" ⇒ lastSender.toString
|
||||||
|
}
|
||||||
|
expectNoMsg(100.millis)
|
||||||
|
if (gotit.size != N) {
|
||||||
|
fail(s"got only ${gotit.size} from \n${gotit mkString "\n"}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -74,7 +74,7 @@ private[akka] trait Dispatch { this: ActorCell ⇒
|
||||||
/**
|
/**
|
||||||
* Start this cell, i.e. attach it to the dispatcher.
|
* Start this cell, i.e. attach it to the dispatcher.
|
||||||
*/
|
*/
|
||||||
final def start(): this.type = {
|
def start(): this.type = {
|
||||||
// This call is expected to start off the actor by scheduling its mailbox.
|
// This call is expected to start off the actor by scheduling its mailbox.
|
||||||
dispatcher.attach(this)
|
dispatcher.attach(this)
|
||||||
this
|
this
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ private[akka] object RoutedActorCell {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private[akka] class RoutedActorCell(_system: ActorSystemImpl, _ref: InternalActorRef, _props: Props, _supervisor: InternalActorRef)
|
private[akka] final class RoutedActorCell(_system: ActorSystemImpl, _ref: InternalActorRef, _props: Props, _supervisor: InternalActorRef)
|
||||||
extends ActorCell(
|
extends ActorCell(
|
||||||
_system,
|
_system,
|
||||||
_ref,
|
_ref,
|
||||||
|
|
@ -67,7 +67,11 @@ private[akka] class RoutedActorCell(_system: ActorSystemImpl, _ref: InternalActo
|
||||||
private var _routeeProvider: RouteeProvider = _
|
private var _routeeProvider: RouteeProvider = _
|
||||||
def routeeProvider = _routeeProvider
|
def routeeProvider = _routeeProvider
|
||||||
|
|
||||||
val route = {
|
@volatile
|
||||||
|
private var _route: Route = _
|
||||||
|
def route = _route
|
||||||
|
|
||||||
|
private def startRoute() {
|
||||||
val routeeProps = _props.withRouter(NoRouter)
|
val routeeProps = _props.withRouter(NoRouter)
|
||||||
_routeeProvider = routerConfig.createRouteeProvider(this, routeeProps)
|
_routeeProvider = routerConfig.createRouteeProvider(this, routeeProps)
|
||||||
val r = routerConfig.createRoute(routeeProvider)
|
val r = routerConfig.createRoute(routeeProvider)
|
||||||
|
|
@ -76,7 +80,13 @@ private[akka] class RoutedActorCell(_system: ActorSystemImpl, _ref: InternalActo
|
||||||
if (resizer.isTimeForResize(resizeCounter.getAndIncrement()))
|
if (resizer.isTimeForResize(resizeCounter.getAndIncrement()))
|
||||||
resizer.resize(routeeProvider)
|
resizer.resize(routeeProvider)
|
||||||
}
|
}
|
||||||
r
|
_route = r
|
||||||
|
}
|
||||||
|
|
||||||
|
override def start(): this.type = {
|
||||||
|
startRoute()
|
||||||
|
// create the routees before scheduling the Router actor
|
||||||
|
super.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue