tkawachi Blog

Akka Memo

Scala 2.10 から付いてくる Akka の Actor についてのお勉強メモ。 全然まとまっていないが晒しておく。

概念

Actor

akka.actor.Actor。 メッセージを受けて処理をする人。

Mailbox

Actorへのメッセージが溜まるところ。

Supervision

Actor間の依存関係のこと。 Actorインスタンスはツリー構造になっている。 親が supervisor となる。

Actor が失敗したらどうするかは supervisor の actor が制御する。

親 actor が shutdown したら、その子どもは全て shutdown する。

タスクのまとまり毎にサブツリーを形成するようにすると良いらしい。

Actor Path

Actorインスタンスにはツリー構造上の位置を表す文字列がついており、これを actor path と呼ぶ。 /, /user, /user/abc など。

ActorSystem

akka.actor.ActorSystem。 ツリー全体を管理するもの。 ActorSystemはスレッドを何本も使う重い構造なので沢山作りすぎない。

Router

Actor の一種。メッセージを受け取って他の actor に投げる(Routingする)。 投げられる側を routee と呼ぶ。 Routee は router の子どもになる。

以下の様な router が提供されている。どのようにルーティングするかは名前から大体想像がつく。 ロードバランサ的なやつですかね。

  • akka.routing.RoundRobinRouter
  • akka.routing.RandomRouter
  • akka.routing.SmallestMailboxRouter
  • akka.routing.BroadcastRouter
  • akka.routing.ScatterGatherFirstCompletedRouter
  • akka.routing.ConsistentHashingRouter

Props

akka.actor.Props。 Actorをインスタンス化する際の設定。 Immutable なので複数の actor をインスタンス化する際に使いまわせる。

ライフサイクル

生まれてから死ぬまで。

停止信号を受け取ると以下の手順で止まる。

  1. mailbox メッセージの処理をやめる
  2. 子どもに停止信号を送る
  3. 全ての子どもから停止完了がくるのを待つ
  4. 自分自身の停止完了プロセスを実行
    1. postStop() を呼び出す
    2. mailbox をダンプ
    3. DeathWatch に停止完了を知らせる
    4. 親に停止完了を知らせる

止めかたのパターン

  • ActorSystem を shutdown() する。
  • PoisonPill を actor に送る。通常メッセージと同じように mailbox に送られ、処理されるときに actor が停止する。
  • context.stop(self), context.stop(child) で止める。

殺しかた

  • Kill を送ると即座に死ぬ

問題が起きたときの判断

以下のいずれか。

  • Resume
  • Restart
  • Terminate
  • Escalate

Restart

  • 子どもをterminate。自分をterminate。
  • 子どもの mailbox は保持される。 mailbox を破棄したい時は supervisor が terminate, recreate すること。

ストラテジー

  • one-for-one strategy – default
    • Restart (defaultDecider)
  • all-for-one strategy

What Restarting Means

失敗は3つのカテゴリに分けられる。

  • 特定のメッセージを処理する際のプログラムエラー
  • メッセージを処理する際に使われる外部リソースの一時的なエラー
  • Actorの内部状態が壊れた

内部状態が壊れたら内部状態を破棄しなければならない。Supervisorや他の子どもが壊れた内部状態の影響を受けなければ、restartするのがベスト。 Restartの際には内部的に新しい Actor がインスタンス化され、ActorRefの参照しているものが切り替わる。 ActorRef の存在意義のひとつは、この切り替え。

Actorが内部で作った子 Actor の ActorRef を外部に保持していると、 Actor restart 時に無効な参照になる。

ガーディアン直下の actor に対応する ActorRef は ActorSystem 終了時まで有効だろうと思う。

Comments