PRMPの動作について

PRMPのモデルはJavaRMIを参考にしていますが、JavaRMIのようなリモートオブジェクトコンパイラ(rmic)や レジストリサーバ(rmiregistry)が存在するわけではありません。

PRMP動作イメージ (サービスドメイン)

runnung_image1.png

動作としては、まず、remote message serverありき。で、client applicationの要求にしたがって、 client stubが remote message serverにメッセージを送って、メソッドの代理実行を依頼する。
って感じです。

PRMP動作イメージ (マシンドメイン)

複数のマシンでremote message serverを使う場合はこんなイメージになります。

runnung_image4.png


事前に

利用を開始する前に、PRMPのサーバ(remote message server)を起動します。

php remote_message_server.php

インスタンス生成

1. client applicationが対象のクラス(client stubの派生クラス)をインスタンス化すと、client stubは設定値を元に特定のremoto message serverに接続する。
2. remoto message serverはclient stubから接続があると自らをforkして子プロセスを生成する。以後、その子プロセスがメッセージの処理を受け持つ。
3. client stubはremote message server(子プロセスのほう)に対象のクラスのCREATEメッセージを送信する(request)。
3. remoto message serverはそのメッセージの内容に従い、適切なクラスを探し出して自らの配下でインスタンス化(以下、server instanceと呼ぶ)する。
4. remote message serverはインスタンス化に成功した旨をclient stubに返答する(response)。
5. client stubは処理を client applicationに戻す。

メソッド呼び出し

1. client applicationがclient instanceのメソッドを呼ぶと、PRMPのclient stubが適切なXML-RPCメッセージをremote message serverに送信する(request)。
2. remoto message serverはXML-RPCメッセージの内容から自己の配下にある適切なserver instanceのメソッドを呼び、その戻り値を得る。
3. server instanceからの戻り値はremote message serverにより、XML-RPCメッセージに変換され、client stubへ返信される(response)。
4. client stubは受信したXML-RPCメッセージを client methodの戻り値として client applicationに返す。

インスタンス破棄

1. client applicationがclient instanceの参照を失うと、PHPは client instanceを破棄しようとしデストラクタ__destruct()を呼び出す。
2. client stub内の___destruct()は、server instanceの削除メッセージをremoto message managerに送信する。(request)
3. remote message serverは対応するserver instanceを削除し、その結果をclient stubに返信し(response)、自身のプロセスを破棄する。
4. client stubは処理を client applicationに戻し、自らが破棄されていく。

メッセージ

クライアント/サーバ間でXML-RPCに準拠したメッセージを投げ合っています。
ただし、httpは使っていません。remote message serverがただのtcpストリームで通信しています。

クライアントはメッセージ内の <methodName>タグを利用してremote_message_server.phpに要求を送信します。
methodNameタグは直接的なメソッド名を記述するのではなく、remote_message_server.phpへの操作メッセージを記述します。

定義済みmethodName (操作メッセージ)

CREATE
    パラメタでで指定されたクラスのインスタンス生成。
DESTROY
    インスタンスの破棄。
METHOD.method_name
    メソッド呼び出し
    インスタンスのmethod_nameを呼ぶ。(メッセージを送る)

投げ合ってるメッセージの例

■CREATE
request: (client -> server)

<?xml version="1.0" encoding="utf-8"?>
<methodCall>
  <methodName>CREATE</methodName>
  <params>
    <param>
      <value>
        <string>sample_class</string>
      </value>
    </param>
  </params>
</methodCall>

response: (server -> client)

<?xml version="1.0" encoding="utf-8"?>
<methodResponse>
  <params>
    <param>
      <value>
        <boolean>1</boolean>
      </value>
    </param>
  </params>
</methodResponse>

■DESTROY
request: (client -> server)

<?xml version="1.0" encoding="utf-8"?>
<methodCall>
  <methodName>DESTROY</methodName>
  <params>
    <param>
      <value>
        <int>0</int>
      </value>
    </param>
  </params>
</methodCall>

response: (server -> client)

<?xml version="1.0" encoding="utf-8"?>
<methodResponse>
  <params>
    <param>
      <value>
        <boolean>1</boolean>
      </value>
    </param>
  </params>
</methodResponse>

■METHOD
request: (client -> server)

<?xml version="1.0" encoding="utf-8"?>
<methodCall>
  <methodName>METHOD.add</methodName>
  <params>
    <param>
      <value>
        <int>100</int>
      </value>
    </param>
    <param>
      <value>
        <int>200</int>
      </value>
    </param>
  </params>
</methodCall>

response: (server -> client)

<?xml version="1.0" encoding="utf-8"?>
<methodResponse>
  <params>
    <param>
      <value>
       <int>300</int>
      </value>
    </param>
  </params>
</methodResponse>

セッションの維持

PRMPはクライアント/サーバ間でセッションがはられると、対応するインスタンスが破棄されるまで(通常は)その接続を持続します。
これにより、メソッド呼び出しを行っていない時間にクライアント/サーバの両方で無駄なリソースを消費させていますが、メソッド呼び出しへの反応は(たぶん)軽量に行われます。メッセージのやりとりのたびにセッションをはる方法(httpなど)のオーバーヘッドとのトレードオフを考慮し、この方法を採用しました。
また、クライアントのインスタンスが存在ししている間はサーバ側のインスタンスも存在しつづけるので、有限ステートマシンの実装も(論理的には)可能です。試したことないけど。

※注意
現状の実装では、クライアント側のインスタンスを維持したまま、接続先のサーバを変更することができますが、これは現時点ではあまりお勧めできません。将来的に負荷分散を考慮した機能をつけたときに、動的なサーバの切り替えはclient stubの機能に含まれる可能性があるからです。

できること、できないこと。わからないこと。

  • メソッドしか呼べない。インスタンス変数(プロパティ)の変更は対応できない。
  • あくまでもメソッド呼び出しをおこなう仕組みなので、持続的なストリームの送受信はできない。(メソッドをループで呼び続けて、無理矢理ストリーム的に使うことはできるけど。。。)
  • 複雑なクラスの実装はおこなったことがないので、どこまでちゃんと動くかわからない。デザインパターンによっては実行不可能なものもあるかも。

仕様上の問題点

  • tcpセッションで送受信の区切りをつける部分がXML-RPCメッセージのタグに依存しているため、PHPの挙動次第では動かなくなる可能性がある。つまり、確認済みの環境以外での動作は不明ということ。
  • server instanceのmethodのパラメタは常に配列なので、本当の意味で透過的なメソッド実行とはいえない。

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2018-12-30 (日) 22:36:35 (198d)