夢とガラクタの集積場

落ちこぼれ三流エンジニアである管理人の夢想=『夢』と、潰えた夢=『ガラクタ』の集積場です。

Akka Actorの設定を設定ファイルから読み込む

こんにちは。

前回に設定ファイルの設定方法について確認したので、
今回は実際に設定ファイルからActorの定義を読み込めるか試してみます。

参考:
Configuration − Akka Documentation
Routing − Akka Documentation

1. 設定ファイルからActor(Router)の定義を読み込む

Actorの設定自体は下記のように設定ファイルに記述することで、
「router1」という名称を指定したルータのルーティング定義として読み込めるようです。

akka.actor.deployment配下が個々のActorの定義、となっているようですね。
■application.conf

akka.actor.deployment {
  /router1 {
  router = round-robin-pool
  nr-of-instances = 3
  }
}

上記の設定を行ったうえで、アプリケーション側で下記のようにコードを記述します。
■ConfiguredRoutingApp.scala

object ConfiguredRoutingApp extends App {
  override def main(args: Array[String]): Unit = {
    val system = ActorSystem.apply("ConfiguredRoutingApp")
    val router1 = system.actorOf(FromConfig.props(Props[MessagePrintActor]),
      "router1")

    router1 ! "Test1"
    router1 ! "Test2"
    router1 ! "Test3"
    router1 ! "Test4"

    Thread.sleep(5000)
    system.shutdown()
  }
}

■MessagePrintActor.scala

class MessagePrintActor extends Actor {

  def receive = {
    case msg: String => {
      val message = self.path + ": Received String " + msg
      println(message)
    }
  }
}

上記の状態でプログラムを実行すると、結果は下記のようになります。

class MessagePrintActor extends Actor {
akka://ConfiguredRoutingApp/user/router1/$c: Received String Test3
akka://ConfiguredRoutingApp/user/router1/$a: Received String Test1
akka://ConfiguredRoutingApp/user/router1/$b: Received String Test2
akka://ConfiguredRoutingApp/user/router1/$a: Received String Test4

Router配下にMessagePrintActorが3つ生成され、RoundRobin方式で配信されているのがわかりますね。

尚、RoundRobinPoolは下記のようになっています。
そのため、"nr-of-instances"で指定した値を基に子のActorが生成されるのはわかります。
■RoundRobin.scala

final case class RoundRobinPool(
  override val nrOfInstances: Int, override val resizer: Option[Resizer] = None,
  override val supervisorStrategy: SupervisorStrategy = Pool.defaultSupervisorStrategy,
  override val routerDispatcher: String = Dispatchers.DefaultDispatcherId,
  override val usePoolDispatcher: Boolean = false)
  extends Pool with PoolOverrideUnsetConfig[RoundRobinPool] {

  def this(config: Config) =
    this(nrOfInstances = config.getInt("nr-of-instances"),
      resizer = DefaultResizer.fromConfig(config),
      usePoolDispatcher = config.hasPath("pool-dispatcher"))

ですが、何故"router = round-robin-pool"でRoundRobinPoolが呼び出されるのかな、
と思ってreference.confを見てみますと下記のような定義がありました。

    router.type-mapping {
      from-code = "akka.routing.NoRouter"
      round-robin-pool = "akka.routing.RoundRobinPool"
      round-robin-group = "akka.routing.RoundRobinGroup"
      random-pool = "akka.routing.RandomPool"
      random-group = "akka.routing.RandomGroup"
      balancing-pool = "akka.routing.BalancingPool"
      smallest-mailbox-pool = "akka.routing.SmallestMailboxPool"
      broadcast-pool = "akka.routing.BroadcastPool"
      broadcast-group = "akka.routing.BroadcastGroup"
      scatter-gather-pool = "akka.routing.ScatterGatherFirstCompletedPool"
      scatter-gather-group = "akka.routing.ScatterGatherFirstCompletedGroup"
      consistent-hashing-pool = "akka.routing.ConsistentHashingPool"
      consistent-hashing-group = "akka.routing.ConsistentHashingGroup"
    }

そのため、自分で作ったクラスを読み込ませたい場合は
フルでクラス名を指定すればOK、のようです。