コントローラー間のメッセージキューを作った

あるアクションコントローラーから、複数の別のコントローラーに情報を伝達しながら処理を渡したいというニーズがあったので、既存の転送とは別にメッセージキューを利用して計画的な処理チェーンを作成できるようにしてみました。
このアイデアは、Presentation-Abstract-Controllerのエージェント間メッセージ伝送にインスパイアされましたが、別物です。

仕様

  • メッセージ
    • メッセージは、リクエストオブジェクト、レスポンスオブジェクトを持つ。
    • 空のメッセージは単純な処理のたらいまわしとして利用可能。
    • メッセージ本体は発送側と受け側で仕様を決めれば、あとは自由で。
  • スコープ内のブロードキャストメッセージにより永続メッセージも保存できるように。
  • メッセージの作成
    • メッセージクラスのインスタンスとして作成し、宛先やメッセージ本体をセットする。
    • メッセージには複数の宛先をセットできる。
      • 兄弟的なコントローラーに順次処理を指示したり、イベントのnotifyに使える。
    • メッセージは他のメッセージに格納してチェーンできる。
      • メッセージキューの優先順位付けは制御外が基本だが、チェーンを指定して投入することで処理フローを固定化するのに使う。
    • コンストラクタで配列を投入して作成することができる。
    • スコープ毎にキューを作成し、そこにメッセージをキューする。
      • キューは複数のセグメントに分けて、指令を濁らせないようにする。
  • メッセージ作成の自動化
    • メッセージの具体仕様はフレームワーク層ではなくアプリケーション層の問題。FWで自動作成をサポートしない。
    • メッセージの自動作成および受信部分は個別アプリケーションの基底クラス等で作成する方が好ましい。
    • 逆に言えば、そこがメッセージキューの拡張ポイント
      • たとえば、階層型アプリケーションで階層内のコントローラーをリストアップして、宛先CCに投入してイベントを送信するとかという活用が考えられる。
  • コントローラーへの注入処理
    • 転送するアクションコントローラーには通常のディスパッチャを通して処理を渡す
    • 転送は、リクエストを書き変えて、setDispatched(false)という_forward準拠の方法で。
    • すでに転送指示が入っていたら、メッセージキューによる処理は遅延させる。
    • 自コントローラー宛てのメッセージはpreDispatchで受信用メソッドに渡すような処理になる。
    • 次のメッセージへの逐次処理はpostDispatchで、宛先CC、メッセージチェーン、キューからの取り出しの順に優先処理される。

キューの処理エンジンはアクションヘルパーにし、メッセージクラスとスプールクラスを用意してみた。
複雑な指定をするにはよいが、_forwardやアクションスタックの方がシンプル。このメッセージキューが必要になるのは、階層化したMVCによる具体実装やアプリケーション構築時のサービス間の自動連携など、個別アプリケーションの設計フェーズで仕様を厳密にしたいときかもしれない。コントローラー間の連携が多層化すると、リクエストオブジェクトを介した情報の受け渡しだけでは不足になる。もしくはリクエストによる汚染をされたくないような枠組みが欲しいはず。ActionStackでは渡しにくい詳細なコントロールを可能にすることとか。
主に基底クラスレベルで記述しておくべき内容なので、一見すると冗長っぽいですが、自動化が完成すれば、なるほどって感じになるのが理想。
まだまだ、整理しきれていない仕様があるので今後も実装は変化する予定です。
まだ、リリース出来るクオリティではないんですが、来月ぐらいにはサンプルサイトを公開できるようにしたいなぁ・・・
※同様のニーズをお持ちの方、生ソースでツッコミをいただける方、いらっしゃいましたらご意見募集中です

一応おさらい。

Zend Frameworkでコントローラーからコントローラーに処理を移す代表的な方法は下記の通り

  • アクションコントローラーの_forward();
  • アクションコントローラーのrunを呼ぶ。(Page Controllerパターン用の実装)
  • アクションスタック
  • リダイレクト
  • ビュースクリプトのアクション呼び出し

そのほか、スタティックメソッドを用意する方法がないわけではないが、これはFWの枠からかなり外れるので普通はしないでしょう。
ビュースクリプトからのアクション呼び出しも、限定的な使用にとどまるはず。

_forwardとアクションスタックは、ディスパッチャーを介した正当派のたらい廻しなので、これが王道。一連のディスパッチ処理を共通にしておくことで、セキュリティ実装その他、プラグインで供給される機能を漏れなく利用することができる。

※ブックマークコメントありがとうございます
メッセージの遅延処理を実装しようかどうか迷ってます