読者です 読者をやめる 読者になる 読者になる

Garuda解説 #1

garuda perl

まともにブクマしてもらったの初めてだ*1
というわけで、前回の続き書こうと思います。

動作フェーズ

Plaggerを踏襲しています。
ごちゃごちゃ書くより、Garuda.pmのコード見てもらえれば一目りょう然ですね。
ざっくりと書くと以下のような感じになってます。

  • new
    • *initialize
  • run
    • **may_run
    • testフェーズ
      • **dispatch
      • *test.finalize
    • filterフェーズ
      • *filter.failure
      • *filter.result
    • publisフェーズ
      • *publish.pre_run
      • *publish.failure
      • *publish.result
      • *publish.finalize

「*」がMethod、「**」がHookです。ロードしたプラグインに実装されているアトリビュート付きメソッドがこの順序で実行されていきます。
testフェーズでテストを実行しまくってResultオブジェクトを作り、filterでそれをfilterして、publishフェーズで公開(通知、保存等)ですね。
testフェーズだけ特殊なので後述しますが、その他のhookはアトリビュートを「RuleHook」という拡張hookにすることで、ruleを噛ますことが出来ます。rule機構はPlaggerのをまんまパクったので、実装の仕方も、configの記述方もまったく同じです。
「may_run」は、runすると最初に実行され、falseを返すとすぐにreturnするようになっています。何らかの理由で(targetがメンテナンス中とか)実行して欲しくないときなんかにpluginでその辺のコントロールできるよう入れておきました。G::Plugin::FailOverではこれを使っています。

dispatch

testの実行だけは、単純なhook呼び出しとは異なります。G::P::Test::*な名前空間のpluginは以下のように処理されます。

plugin->config->targetの解釈は、ロードしたTargetモジュールによって異なります。デフォはTarget::Simpleになっているので、単純にリストとして解釈します。その他のTargetモジュールの詳細ついてはpod参照。
たとえば、Target::DBICを使用した場合、$model->searchの第一引数にそのまま渡されます。

  - module: Target::DBIC
    connect_info:
      - "dbi:SQLite:/path/to/db"

  - module: Test::Hoge
    target:
      hostname:
        like: 'www%' 

は、

$rs = $model->search({hostname =>{like => 'www%'}}, { columns => [$column] });
return [ map { $_->$column } $rs->all ];

となります。columnのデフォはプライマリキーです。
で、その後のフェーズでは、こんな感じで他カラムをhashrefで参照可能なので、テンプレートでごにょごにょしたり出来ます。

$result->failures->[0]->target->info();

DispachプラグインのデフォはDispach::Simpleになっているので、特にロードしない限りはシーケンシャルに実行して行きますが、Dispach::Gearmanを使うと、並列、分散処理が可能になります。testの内容が軽く、Gearman周りのオーバーヘッドの方が気になる場合は、Simpleの方が早い場合もあると思います。

他のフェーズについてはまた後日書く(かもしれない)。
もし、使ってくれて、気になることがありましたらメール(特定のircチャンネルに常駐したりしてないので。。)ください。開発に参加してくれる方も募集しています。
今後はプラグインは増やしていく予定。とりあえずAssurerのを順次移植していこうと思います。

*1:その内の一人が実兄ってのが微妙だが。。