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 をインスタンス化する際に使いまわせる。
ライフサイクル
生まれてから死ぬまで。
停止信号を受け取ると以下の手順で止まる。
- mailbox メッセージの処理をやめる
- 子どもに停止信号を送る
- 全ての子どもから停止完了がくるのを待つ
- 自分自身の停止完了プロセスを実行
postStop()
を呼び出す- mailbox をダンプ
DeathWatch
に停止完了を知らせる- 親に停止完了を知らせる
止めかたのパターン
- 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
失敗は3つのカテゴリに分けられる。
- 特定のメッセージを処理する際のプログラムエラー
- メッセージを処理する際に使われる外部リソースの一時的なエラー
- Actorの内部状態が壊れた
内部状態が壊れたら内部状態を破棄しなければならない。Supervisorや他の子どもが壊れた内部状態の影響を受けなければ、restartするのがベスト。 Restartの際には内部的に新しい Actor がインスタンス化され、ActorRefの参照しているものが切り替わる。 ActorRef の存在意義のひとつは、この切り替え。
Actorが内部で作った子 Actor の ActorRef を外部に保持していると、 Actor restart 時に無効な参照になる。
ガーディアン直下の actor に対応する ActorRef は ActorSystem 終了時まで有効だろうと思う。