PROBLEM

  • Elixirをさわりはじめてしばらく経つけどふかく理解した気になれない
  • Phoenixやほかのフレームワークに頼られないケースが出てきたとき自由な発想ができるようになっておきたい
  • 巷でいわれているSLA 99.9999999% などの実際がどうなのか腹落ちしてない

-

SOLUTION

というわけで、LYSE本を読むことにした。Elixirに関係ありそうな箇所を選定している。

今回はアプリケーションの作成。

15. リマインダーアプリケーション

  • 仕様
    • イベントを追加
      • イベントには締切り(警告する時間)、イベント名、詳細が含まれます
    • イベントの時間が来たら警告
    • イベント名でイベントをキャンセル
    • 永続的なディスク保存先を持たない
        • これは今回見ようとしているのアーキテクチャの概念を示すのに必要ありません
        • これは実際のアプリケーションを作るなら全然ダメなことですが、代わりにもし実装したくなったらその機能はどこに挿入されるかを示して、ちょっとだけその実装の手助けになる関数も示します
      • 永続化保存先がないとした場合、実行中にコードを更新しなければいけません
    • ソフトウェアとのやりとりはコマンドライン経由で
      • あとでこれは拡張できる
        • たとえばGUI、Webページアクセス、IMソフト、メールなど
  • ユースケース
    • Client
      • イベントサーバをサブスクライブして、メッセージとして通知を受ける
        • こうすることで、すべてイベントサーバをサブスクライブしている多くのクライアントを設計するのが簡単になる
        • 各クライアントは潜在的に、前述した異なるゲートウェイとなる
          • GUI、Webページ、IMソフト、メールなど
      • サーバにイベントを詳細情報とともに追加するように依頼
      • サーバにイベントをキャンセルするように依頼
      • サーバを(落ちたかどうか知る為に)監視
      • 必要があればイベントサーバを終了
    • Event Server
      • メソッド
        • クライアントからのサブスクライブを受取
        • イベントプロセスから出された通知を各サブスクライバに転送
        • イベントを追加するためにメッセージを受取
          • 必要なX, Y, Zプロセスを起動
        • イベントキャンセルのメッセージを受取
          • イベントプロセスを殺す
        • クライアントから終了できる
        • シェルから自分自身のコードを再読込出来る
      • Process X, Y, Z
        • 発報が待たれる通知を表す
          • 天気にはイベントサーバにリンクされたタイマーに過ぎない
        • 時間が来たらイベントサーバにメッセージを送る
        • キャンセルのメッセージを受け取って死ぬ
  • 実装
    • ディレクトリ構成
      • ebin/
      • include/
      • priv/
      • src/
        • event.erl - event module
          • loop/1
          • normalize/1
          • start/2
          • start_link/2
          • cancel/1
          • time_to_go/1
          • init/3
        • evserv.erl - event server
          • loop/1
          • valid_datetime/1
          • valid_time/1
          • valid_time/3
          • send_to_clients/2
          • start/0
          • start_link/0
          • terminate/0
          • subscribe/1
          • add_event/3
          • add_event2/3
          • cancel/1
          • listen/1
          • init/0
        • sup.erl - supervisor
          • start/2
          • start_link/2
          • init/1
          • loop/1
      • Emakefile
          {'src/*', [debug_info,
                     {i, "src"},
                     {i, "include"},
                     {outdir, "ebin"}]}.
        
$ erl -make && erl -pa ebin/
Erlang/OTP 19 [erts-8.1] [source] [64-bit] [smp:2:2] [async-threads:10] [kernel-poll:false]

Eshell V8.1  (abort with ^G)
1> evserv:start().
<0.59.0>
2> evserv:subscribe(self()).
{ok,#Ref<0.0.2.84>}
3> evserv:add_event("Hey there3", "test", { {2017, 7, 9}, {1, 23, 59} }).
ok
4> evserv:listen(2000).
[{done,"Hey there3","test"}]

TIPS

  • Erlangのタイムアウト値はミリ秒でおよそ50日に制限されている

-

以上 :droplet: