Error handling in Erlang and Scala

2,843 views
2,730 views

Published on

Published in: Technology
0 Comments
9 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,843
On SlideShare
0
From Embeds
0
Number of Embeds
155
Actions
Shares
0
Downloads
10
Comments
0
Likes
9
Embeds 0
No embeds

No notes for slide

Error handling in Erlang and Scala

  1. 1. Actor とエラーハンドリング ∼Erlang 時々 Scala∼ M.Ikuta(@cooldaemon) Sep.4,2011 1
  2. 2. 自己紹介決済代行会社のプログラマ 某大手クーポンサイトの決済システム iPhone + ScanJacket Erlang 基礎勉強会や分散処理勉強会の主催 2
  3. 3. モチベーション何故、エラーハンドリングの知識が必要か?堅牢なシステムを構築したい休日に家族サービスができる 3
  4. 4. モチベーション何故、エラーハンドリングの知識が必要か?堅牢なシステムを構築したい休日に家族サービスができる3DS の稟議が通る 3
  5. 5. モチベーション並行や分散を取り入れるとシステムが複雑に?並行や分散だからこそ堅牢なシステムを作れる! 4
  6. 6. 本日のお題Erlang と Scala の紹介Actor モデルリンクによる相互監視Supervisor Tree Error Logger 例外 5
  7. 7. 本日のお題Erlang と Scala の紹介Actor モデルリンクによる相互監視Supervisor Tree Error Logger 例外 6
  8. 8. Erlang と Scala の紹介 何故、Actor モデルの話をするために Erlang と Scala を選んだのか? 私が他の Actor モデルを実装したライブラ リや言語を知らない 本日、話す予定のリンクによる相互監視が、 他の Actor 実装に採用されているか不明 7
  9. 9. Erlang と Scala の紹介 Erlang  ネットワークサーバを作るための DSL 並行と分散が得意 高い耐障害性 稼働率 99.9999999% も夢ではない 8
  10. 10. Erlang と Scala の紹介 Erlang  Yaws, Mochiweb, RabbitMQ, CouchDB, Hibari, Riak, Kai, Scalaris, Ejabberd, etc.. Tsung や BashoBench のような負荷試験 ツールも作りやすい モジュールや関数を物理的に離れたノードに転 送できるので MapReduce なども得意 9
  11. 11. Erlang と Scala の紹介 Scala  様々な言語の長所を集めた次世代言語 夢と希望が詰ってる 並行処理に関連するキーワードだけでも… Thread, Actor, 部分継続, 並列コレク ション, 非同期IO, CAS, STM, etc.. 10
  12. 12. Erlang と Scala の紹介 Scala  選択肢が多く、組み合わせも自由 Actor + STM  Actor + 継続 Actor + 非同期IO 継続 + 非同期IO 11
  13. 13. 本日のお題Erlang と Scala の紹介Actor モデルリンクによる相互監視Supervisor Tree Error Logger 例外 12
  14. 14. Actor モデル 13
  15. 15. Actor モデル並行に動作する計算実体 13
  16. 16. Actor モデル並行に動作する計算実体 もう少し詳しい話をこれからするので、知って る人は寝てて OK 13
  17. 17. Actor モデル世の中の全ては Actor である全ての Actor は並行に動作するActor は、個々にローカルメモリを持ち、Actor 間でメモリ共有を行わないActor は、自分自身や他の Actor とメッセージを送受信しながら処理を行う 14
  18. 18. Actor モデルActor は、メッセージを受信するためにメールアドレスとメールボックスを持つメッセージは、メールアドレス宛に送信されるメッセージは、メールボックスに格納されるメッセージは必ず届いて処理される 15
  19. 19. Actor モデルメッセージの送信は非同期に行われるメッセージ受信の順番は保証されていないメールボックスから任意のメッセージを取り出せるActor は、新たな Actor を作成できる 16
  20. 20. Actor モデルErlang と Scala には実装されていないが… Actor はノードを越えて移動できる 暇なノードへ働きに行ったり 壊れたノードから逃げたり 17
  21. 21. Actor モデル Mailbox Actor Mailbox Actor message message receive Receive SendMessage Message Create Mailbox Actor 18
  22. 22. 本日のお題Erlang と Scala の紹介Actor モデルリンクによる相互監視Supervisor Tree Error Logger 例外 19
  23. 23. リンクのよる相互監視リンク 二つの Actor 間のエラー伝播経路を定義 二つの Actor がリンクされている場合、一方 の Actor が停止すると、もう一方に EXIT シ グナルが送られる 20
  24. 24. リンクのよる相互監視EXIT シグナル Actor が停止する際に自動的に生成される(故 意に生成する事もできる) 停止する Actor とリンクしている全ての Actor へブロードキャストされる EXIT シグナルには停止理由が含まれる 21
  25. 25. リンクのよる相互監視 A Link B A B EXIT A B A 22
  26. 26. リンクのよる相互監視 B CA EXIT EXIT B CA CA 23
  27. 27. リンクのよる相互監視 B C A EXIT B C A EXIT A B A 24
  28. 28. リンクのよる相互監視EXIT シグナル EXIT シグナルを受信した Actor は、 trap_exit が true か否かで動作が異なる Erlang では、trap_exit が true の Actor をシステムプロセスと呼ぶ 25
  29. 29. リンクのよる相互監視 システムプロセス(Erlang)trap_exit 停止理由 動作 TRUE kill 停止:killed をブロードキャスト TRUE X {EXIT, Pid, X} をメールボックスに追加 FALSE normal 無視 FALSE kill 停止:killed をブロードキャスト FALSE X 停止:X をブロードキャスト 26
  30. 30. リンクのよる相互監視 システムプロセス(Scala)trap_exit 停止理由 動作 TRUE X Exit(Actor, X) をメールボックスに追加 FALSE normal 無視 FALSE X 停止:X をブロードキャスト 27
  31. 31. リンクのよる相互監視リンクの利点 故障箇所を Actor (やノード)に隔離できる 大怪我ではなく、擦り傷で済む 依存関係がある Actor をまとめて停止できる 一方がシステムプロセスであれば、停止を検知 してエラー処理を行える 28
  32. 32. リンクのよる相互監視リンクの利点 リンクはノードを越えて行える 監視 Actor と Worker Actor を、それ ぞれ、物理的に離れた別ノードに配置できる 障害が発生した信頼できない Actor(やノー ド)にエラー処理を任せない 29
  33. 33. リンクのよる相互監視エラー処理は… 監視している Actor が処理を引き継ぐ 停止した Actor を再起動 処理を引き継ぐ Actor を別ノードに作る 社内監視システムにエラー通知を行う etc… 30
  34. 34. リンクのよる相互監視リンクの利点 コードがスッキリする 31
  35. 35. リンクのよる相互監視 JavaScriptif (is_success()) { do_samething();} else { throw "Exception";} 32
  36. 36. リンクのよる相互監視 Erlangok = is_success(),do_samething().ok 以外で例外 {badmatch, 戻り値} が発生 33
  37. 37. リンクのよる相互監視 JavaScriptvar num = get_number();switch (num) { case 1: do_samething1(); break; case 2: do_samething2(); break; default: throw "Exception: " + num; break;} 34
  38. 38. リンクのよる相互監視 Erlang case get_numer() of 1 -> do_samething1(); 2 -> do_samething2() end.1, 2 以外で例外 {case_clause, 戻り値} が発生 35
  39. 39. リンクのよる相互監視 Erlang do_samething(get_number()). do_samething(1) -> do_samething1(); do_samething(2) -> do_samething2().1, 2 以外で例外 {function_clause, 戻り値} が発生 36
  40. 40. リンクのよる相互監視 ScalagetNumber() match { case 1 => doSamething1() case 2 => doSamething2()}例外 scala.MatchError が発生するが、Actor内ならリンク先に Exit(Actor, Exception) 37
  41. 41. リンクのよる相互監視リンクの利点 コードがスッキリする 異常事態を考慮したコードを書く必要がない その場でウダウダせずに、システム全体の構 造により頑健性を担保する 38
  42. 42. リンクのよる相互監視リンクの利点 コードがスッキリする とは言え…回復不能な想定外の異常事態が発 生した場合の処理のみ省略する事!! 39
  43. 43. 本日のお題Erlang と Scala の紹介Actor モデルリンクによる相互監視Supervisor Tree Error Logger 例外 40
  44. 44. Supervisor TreeActor リンクを木状に構成したもの木の上位にある Actor(trap_exit=true)が下位の Actor を監視する監視専用の Actor を Supervisor と呼ぶ Erlang OTP Akka 41
  45. 45. Supervisor Tree個人的な設計原則 全ての Actor は Supervisor 配下に設置 Application:Supervisor Tree = 1:1  42
  46. 46. Supervisor Tree全ての Actor は Supervisor 配下に設置 Actor が孤独死するシステムは堅牢ではない 43
  47. 47. Supervisor TreeApplication:Supervisor Tree = 1:1  Supervisor を複数使いたい? Root の Supervisor の下に、それらの Supervisor を設置して一元管理 44
  48. 48. Supervisor Tree Supervisor Worker Worker Supervisor Worker Worker Worker 45
  49. 49. Supervisor TreeSupervisor の仕事 配下の Actor の起動と停止に特化 他の余計な仕事は行わない 46
  50. 50. Supervisor TreeSupervisor 毎の設定(抜粋) 停止した Actor のみ再起動(one_for_one) 停止した Actor と同じ Supervisor 配下の Actor を全て再起動(one_for_all) 47
  51. 51. Supervisor TreeSupervisor 毎の設定(抜粋) 一定の秒数以内に一定の回数以上 Worker の起 動停止を繰り返したら Supervisor を終了 再起動しても何度も同じ理由で停止する状態 を避ける 48
  52. 52. Supervisor TreeWorker 毎の設定(抜粋) 必ず再起動(permanent) 異常終了した場合だけ再起動(transient) 再起動しない(temporary) 終了処理のタイムアウト時間 49
  53. 53. 本日のお題Erlang と Scala の紹介Actor モデルリンクによる相互監視Supervisor Tree Error Logger 例外 50
  54. 54. Error Loggerエラーハンドリングの仕組みErlang OTP Erlang では、catch されなかった例外はError Logger で処理されるOTP の Event Manager Behaviour で作られている Erlang Behaviour = Scala Trait 51
  55. 55. Error LoggerEvent Manager  予め任意の Event に幾つかの Event Handler を登録しておくと、その Event が 発生した際に、登録済みの複数の Event Handler を全て実行する 52
  56. 56. Error Loggerデフォルトで、エラーログを TTY に出力するError Handler が登録されているOTP の System Application SupportLibraries(SASL) を起動すると… エラーログをファイルに残す エラーログファイルをローテションするなどの設定ができる Error Handler を追加する 53
  57. 57. Error LoggerSASL の Error Handler 速度を上げるため、バイナリ形式でログを残す 専用のログを読むアプリケーション(rb)を使 用しないとログが読めない エラーメッセージが少し解り難い 54
  58. 58. Error LoggerLagger  SASL が性に合わない人向け Riak の Basho 製 解りやすいメッセージをテキスト形式でファイ ルに保存してくれる Handler が登録される 55
  59. 59. Error LoggerScala(提案) Event Manager Trait を作る Event Manager Trait を extends した Error Logger Actor を作る Error Logger にメッセージを送る Trait を作る 56
  60. 60. 本日のお題Erlang と Scala の紹介Actor モデルリンクによる相互監視Supervisor Tree Error Logger 例外 57
  61. 61. 例外最後に Actor とは関係無いのですが、Erlangと Scala の例外についての余談をさせてください 58
  62. 62. 例外Erlang  Erlang には三つの例外がある error  throw  exit  59
  63. 63. 例外Erlang  error  システムエラーであり、呼び出し側が対処で きないエラーである場合に使用する 意図的に起こす事もできるが、パターンマッ チの失敗等で自動的に発生する error は catch 非推奨 60
  64. 64. 例外Erlang  throw  呼び出し側が対処できるかもしれないエラー である場合に使用する 呼び出し側は、対処できないと判断した場 合、無理に catch しなくとも良い 61
  65. 65. 例外Erlang  exit  Actor を停止する際に使う 62
  66. 66. 例外 Erlangtry foo(), bar()catch error:foo -> handle_foo(); throw:bar -> handle_bar(); Class:Exception -> handle_error(Class, Exception)after baz()end. 63
  67. 67. 例外Scala  チェック例外が無い 例外は、なるべく異常事態に限定する Actor や STM の内部での利用は必要悪 Java の throw 宣言されているメソッドを使 用する際、catch しなくともコンパイル時にエ ラーとはならない 64
  68. 68. 例外Scala  回復可能な想定内のエラーは、Option や Either に包んで返す Java メソッドの例外は、 scala.util.control.Exception.allCatch  で Option/Either に包む 65
  69. 69. 例外 Scalaimport scala.util.control.Exception.allCatchdef foo(): Either[Throwable, Foo] = allCatch either{new JavaFoo}def bar(objFoo: Foo): Either[Throwable, Bar] =allCatch either {new JavaBar(objFoo)}val result: Either[Throwable, Bar] = for { objFoo <- foo().right objBar <- bar(objFoo).right} yield objBar 66
  70. 70. ご清聴ありがとうございました 67

×