in actor/src/main/scala/org/apache/pekko/actor/ActorRefProvider.scala [659:757]
def actorOf(
system: ActorSystemImpl,
props: Props,
supervisor: InternalActorRef,
path: ActorPath,
systemService: Boolean,
deploy: Option[Deploy],
lookupDeploy: Boolean,
async: Boolean): InternalActorRef = {
props.deploy.routerConfig match {
case NoRouter =>
if (settings.DebugRouterMisconfiguration) {
deployer.lookup(path).foreach { d =>
if (d.routerConfig != NoRouter)
log.warning(
"Configuration says that [{}] should be a router, but code disagrees. Remove the config or add a routerConfig to its Props.",
path)
}
}
def parentDispatcher: String = supervisor match {
case withCell: ActorRefWithCell => withCell.underlying.props.dispatcher
case _ => Deploy.NoDispatcherGiven
}
val props2 =
// mailbox and dispatcher defined in deploy should override props
(if (lookupDeploy) deployer.lookup(path) else deploy) match {
case Some(d) =>
(d.dispatcher, d.mailbox) match {
case (Deploy.NoDispatcherGiven, Deploy.NoMailboxGiven) => props
case (Deploy.DispatcherSameAsParent, Deploy.NoMailboxGiven) => props.withDispatcher(parentDispatcher)
case (dsp, Deploy.NoMailboxGiven) => props.withDispatcher(dsp)
case (Deploy.NoDispatcherGiven, mbx) => props.withMailbox(mbx)
case (Deploy.DispatcherSameAsParent, mbx) => props.withDispatcher(parentDispatcher).withMailbox(mbx)
case (dsp, mbx) => props.withDispatcher(dsp).withMailbox(mbx)
}
case _ =>
// no deployment config found
if (props.deploy.dispatcher == Deploy.DispatcherSameAsParent)
props.withDispatcher(parentDispatcher)
else
props
}
if (!system.dispatchers.hasDispatcher(props2.dispatcher))
throw new ConfigurationException(s"Dispatcher [${props2.dispatcher}] not configured for path $path")
try {
val dispatcher = system.dispatchers.lookup(props2.dispatcher)
val mailboxType = system.mailboxes.getMailboxType(props2, dispatcher.configurator.config)
if (async)
new RepointableActorRef(system, props2, dispatcher, mailboxType, supervisor, path).initialize(async)
else new LocalActorRef(system, props2, dispatcher, mailboxType, supervisor, path)
} catch {
case NonFatal(e) =>
throw new ConfigurationException(
s"configuration problem while creating [$path] with dispatcher [${props2.dispatcher}] and mailbox [${props2.mailbox}]",
e)
}
case router =>
val lookup = if (lookupDeploy) deployer.lookup(path) else None
val r = (router :: deploy.map(_.routerConfig).toList ::: lookup.map(_.routerConfig).toList).reduce((a, b) =>
b.withFallback(a))
val p = props.withRouter(r)
if (!system.dispatchers.hasDispatcher(p.dispatcher))
throw new ConfigurationException(s"Dispatcher [${p.dispatcher}] not configured for routees of $path")
if (!system.dispatchers.hasDispatcher(r.routerDispatcher))
throw new ConfigurationException(s"Dispatcher [${p.dispatcher}] not configured for router of $path")
val routerProps = Props(
p.deploy.copy(dispatcher = p.routerConfig.routerDispatcher),
classOf[RoutedActorCell.RouterActorCreator],
Vector(p.routerConfig))
val routeeProps = p.withRouter(NoRouter)
try {
val routerDispatcher = system.dispatchers.lookup(p.routerConfig.routerDispatcher)
val routerMailbox = system.mailboxes.getMailboxType(routerProps, routerDispatcher.configurator.config)
// routers use context.actorOf() to create the routees, which does not allow us to pass
// these through, but obtain them here for early verification
val routeeDispatcher = system.dispatchers.lookup(p.dispatcher)
system.mailboxes.getMailboxType(routeeProps, routeeDispatcher.configurator.config)
new RoutedActorRef(system, routerProps, routerDispatcher, routerMailbox, routeeProps, supervisor, path)
.initialize(async)
} catch {
case NonFatal(e) =>
throw new ConfigurationException(
s"configuration problem while creating [$path] with router dispatcher [${routerProps.dispatcher}] and mailbox [${routerProps.mailbox}] " +
s"and routee dispatcher [${routeeProps.dispatcher}] and mailbox [${routeeProps.mailbox}]",
e)
}
}
}