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.
|
||||
*/
|
||||
final def start(): this.type = {
|
||||
def start(): this.type = {
|
||||
// This call is expected to start off the actor by scheduling its mailbox.
|
||||
dispatcher.attach(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(
|
||||
_system,
|
||||
_ref,
|
||||
|
|
@ -67,7 +67,11 @@ private[akka] class RoutedActorCell(_system: ActorSystemImpl, _ref: InternalActo
|
|||
private var _routeeProvider: RouteeProvider = _
|
||||
def routeeProvider = _routeeProvider
|
||||
|
||||
val route = {
|
||||
@volatile
|
||||
private var _route: Route = _
|
||||
def route = _route
|
||||
|
||||
private def startRoute() {
|
||||
val routeeProps = _props.withRouter(NoRouter)
|
||||
_routeeProvider = routerConfig.createRouteeProvider(this, routeeProps)
|
||||
val r = routerConfig.createRoute(routeeProvider)
|
||||
|
|
@ -76,7 +80,13 @@ private[akka] class RoutedActorCell(_system: ActorSystemImpl, _ref: InternalActo
|
|||
if (resizer.isTimeForResize(resizeCounter.getAndIncrement()))
|
||||
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