ページの先頭行へ戻る
Interstage Application Server アプリケーション作成ガイド(CORBAサービス編)

4.3.1 インスタンス管理とアプリケーション形態

4.3.1.1 アプリケーション形態の種別

    サーバアプリケーションは、Servant(インタフェース実装部)のインスタンスの管理方法により以下の4つの形態をとることができます。
  以下のように要件によりアプリケーション形態を選択してください。



デフォルトインスタンス方式

  各クライアントが同一のServantオブジェクトを使用する方式です。つまり、クライアントごとのインスタンス管理をしない方式です。
  各クライアントは以下のように同一のServantのインスタンスを使用します。


Factory-1方式

  クライアントごとに異なるServantオブジェクトを使用する方式です。
  クライアントごとのインスタンス管理をPOAオブジェクトで行う方式です。Factory内で、オブジェクトリファレンスおよびインスタンスの作成を行います。


Factory-2方式

  クライアントごとに異なるServantオブジェクトを使用する方式です。
  クライアントごとのインスタンス管理をPOAオブジェクトで行う方式です。Factory内でオブジェクトリファレンスの作成を行い、リクエスト受信時にServantManagerオブジェクト内でインスタンスを作成します。

  Factoryはリクエストごとにオブジェクトリファレンスやインスタンスを作成するオブジェクトであり、インスタンス管理を行う場合に必要となるオブジェクトです。
  AOMはActive Object Mapのことであり、インスタンスの管理テーブルのことです。
  AOM、ServantManager等の詳細については、“4.3.2 POA概要”を参照してください。
  Factory-1方式およびFactory-2方式の各クライアントは以下のように、クライアントごとに異なるServantのインスタンスを使用します。



[Factory-1方式とFactory-2方式の違い]

  Factory-1方式はFactory内で事前にインスタンスを作成しておくことができるため、リクエストを受信した時点でインスタンスを作成するFactory-2より性能的には若干優れます。
  Factory-2方式はリクエストを受信した時点でインスタンスを作成するので、Factory内で事前のインスタンスを作成しておくFactory-1より資源的には若干優れます。


ユーザインスタンス管理方式

  インスタンス管理をユーザの作成するServantManagerオブジェクトに任せる方式です。
  各クライアントは以下のように、クライアントごとに異なるServantのインスタンスを使用します。インスタンスはユーザの作成したServantManagerオブジェクト内のインスタンス管理テーブルで行われます。



[アプリケーション形態の選択]

  アプリケーション形態は、Servantオブジェクトの属するPOAオブジェクトのServantRetentionポリシ、RequestProcessingポリシの指定により決まります。組み合わせ方を以下に示します。詳細については、“4.3.2.3 POAオブジェクト”を参照してください。

アプリケーション形態

ServantRetentionポリシ

RequestProcessingポリシ

デフォルトインスタンス方式

NON_RETAIN

USE_DEFAULT_SERVANT

Factory-1方式

RETAIN

任意

Factory-2方式

RETAIN

USE_SERVANT_MANAGER

ユーザインスタンス管理方式

NON_RETAIN

USE_SERVANT_MANAGER

) 表内のポリシは、Servantオブジェクトを管理するPOAポリシに対する設定値を示しています。


[Factoryについて]

  Factoryとは、Servantオブジェクトのインスタンスを生成し、そのオブジェクトリファレンスをクライアントに返すことを目的としたインタフェースです。
  これにより、そのクライアントが専用で使用できるServantオブジェクトのインスタンスをサーバ側に持たせることが可能となります。
  Factoryの概念は、以下のIDL定義によって示されます。前述したFactory-1方式、Factory-2方式を使用する際も、IDL定義で他のインタフェースとともにFactoryインタフェースを定義します。


FactoryIDL定義例(a)】

  //何らかのインタフェース
    interface intf{
        void  op(); 
    };
  //Factoryインタフェース
    interface Factory {
        intf   create();
    };

  上記のIDL定義で示されるように、クライアントはFactoryオブジェクトのオペレーションcreate()を発行することにより、そのクライアントで使用するintfオブジェクトを取得することが可能となります。
  次にクライアントは取得したintfオブジェクトに対し、op()オペレーションを発行することで本来の目的の処理を行います。

  一方サーバ側では、以下の一連の処理をcreate()オペレーションの実装として記述する必要があります。

  1. Servantオブジェクト(intfインタフェースの実装クラスのインスタンス)を生成(new)します。

  2. 生成したインスタンスとオブジェクトリファレンスとの関連付けをPOAのAOMに登録します。

  3. 関連付けられたオブジェクトリファレンスを返します。

  (Factory-2方式ではcreate()オペレーションの実装として3.のオブジェクトリファレンスの生成と復帰だけを行い、1.と2.は要求時にServantManagerオブジェクト内で行います。しかし、クライアント側から見たcreate()オペレーションの機能は同じです)。

  Factoryとは、このようなインタフェースの機能上の概念です。したがって、IDL定義では、Factoryインタフェースの名前(上記の例では“Factory”)や実装するオペレーションの名前(上記の例では“create”)、種類は自由です。しかし、Factoryの目的上、上記のcreate()のような「戻り値としてオブジェクトリファレンスを返す」機能をもつオペレーションが最低限必要となります。

  実際のアプリケーション開発では、生成したServantオブジェクトのインスタンスを解放するためのオペレーションもFactoryに実装することが推奨されます。これによりサーバ資源の節約が可能となります。
  以下のIDL定義の例ではServantオブジェクトのインスタンスを解放するためのオペレーションとしてdestroy()を定義しています。


FactoryIDL定義例(b)

  //何らかのインタフェース
    interface intf{
        void  op(); 
    };
  //Factoryインタフェース
    interface Factory{
        intf  create();
        void  destroy(in intf obj);
    };

  クライアント側では目的の処理が終了した時点で、以前にcreate()メソッドで取得したオブジェクトリファレンスを引数としてdestroy()オペレーションをコールします。一方、サーバ側では渡されたオブジェクトリファレンスに対応するServantオブジェクトをAOMから削除する処理を行います。

  上記のIDLに対するFactoryオブジェクトのcreate()オペレーション、destoroy()オペレーションの実装例を以下に示します。ここでは、intfインタフェースの実装クラスをUserServantクラスとしています。処理の詳細については、“4.3.2 POA概要”以降を参照してください。


【オペレーションの実装例(Factory-1方式)】

      intf_ptr  Factory_impl::create( CORBA::Environment&  env )
                throw( CORBA::Exception )
      {
          intf_ptr       ior; // Servantオブジェクトのオブジェクトリファレンス
          try {
              // 1. Servantオブジェクトの生成
              intf_impl* svt = new intf_impl();
              // 2. AOMへ登録
              poa->activate_object( svt, env );
              //3.オブジェクトリファレンスの生成
              CORBA::Object_var _tmpObj = poa.servant_to_reference( svt, env ); 
              // intf型に変換
              ior = intf::_narrow( _tmpObj ); 
          }
          catch( CORBA::SystemException&  e ) {  /*例外処理*/  }
          return( ior ); 
      }

void  Factory_impl::destroy( intf_ptr obj,
CORBA::Environment&  env )
throw( CORBA::Exception )
{
          try {
              // オブジェクトリファレンスからオブジェクトIDを求める
              PortableServer::ObjectId_var  oid = poa->reference_to_id( obj, env ); 
              // オブジェクトIDからServantを求める
              PortableServer::Servant  svt = poa->id_to_servant( *oid, env );
              // Servantをdeactiveにする(AOMより削除)
              poa->deactivate_object( *oid, env );
              // Servantの削除
              svt->servant_delete();
          }
          catch( CORBA::SystemException&  e ) {  /*例外処理*/  }
      }

) ソース上のpoaはPOAオブジェクトのインスタンス


[Factoryオブジェクトのインスタンスの扱いについて]

  Factoryオブジェクトのインスタンスも通常のServantオブジェクトのインスタンスと同様に、POAに登録する必要があります。
  “4.3.7.2 Active Object Map(AOM)使用例 (Factory-1方式)”や“4.3.7.3 Servant Activator使用例 (Factory-2方式)”等に示した例では、Factoryオブジェクトは「Factory専用のPOA」を使用してDefault Servantとして登録しています。加えてFactory用のPOAはAOMを使用しない設定(NON_RETAINポリシ)としています。
  これは以下の理由によるものです。

4.3.1.2 各アプリケーション形態

(1)デフォルトインスタンス方式

  クライアントごとのインスタンス管理をしない方式です。



  1. OD_or_admコマンドにより事前にServantのオブジェクトリファレンスをNamingServiceに登録します。

  2. サーバアプリケーションはServantを作成します。

  3. サーバアプリケーションはServantをPOAにDefault Servantとして登録します。

  4. クライアントアプリケーションはNamingServiceからオブジェクトリファレンスを獲得します。

  5. クライアントアプリケーションはオペレーションop()を要求します。

  6. POAは登録されているDefault Servantを起動します。

  7. POAはオペレーションop()の結果をクライアントに通知します。


(2)Factory-1方式

  クライアントごとでインスタンス管理をPOAオブジェクトで行う方式です。Factory内で、オブジェクトリファレンスおよびインスタンスを作成します。



  1. OD_or_admコマンドで事前にFactoryのオブジェクトリファレンスをNamingServiceに登録します。

  2. サーバアプリケーションはFactoryを作成します。

  3. サーバアプリケーションはFactoryをDefault ServantとしてPOAに登録します。

  4. クライアントアプリケーションはNamingServiceからFactoryのオブジェクトリファレンスを獲得します。

  5. クライアントアプリケーションはオペレーションcreateをFactoryに要求します。

  6. FactoryはServantのインスタンスを作成します。

  7. FactoryはAOMにインスタンスを登録します。

  8. Factoryはオブジェクトリファレンスを作成してクライアントに通知します。

  9. クライアントアプリケーションはオペレーションop()を要求します。

  10. POAは、AOMを検索して、獲得したインスタンスでServantに対してオペレーションop()の実行を依頼します。

  11. POAは、オペレーションop()の結果をクライアントに通知します。


(3)Factory-2方式

  クライアントごとでインスタンス管理をPOAオブジェクトで行う方式です。Factory内でオブジェクトリファレンスを作成し、リクエスト受信時にServantManagerオブジェクト内でインスタンスを作成します。



  1. OD_or_admコマンドで事前にFactoryのオブジェクトリファレンスをNamingServiceに登録します。

  2. サーバアプリケーションはFactoryを作成します。

  3. サーバアプリケーションはFactoryをDefault ServantとしてPOAに登録します。

  4. サーバアプリケーションはServantManagerを作成します。

  5. サーバアプリケーションはServantManagerをPOAに登録します。

  6. クライアントアプリケーションはNamingServiceからFactoryのオブジェクトリファレンスを獲得します。

  7. クライアントアプリケーションはオペレーションcreateをFactoryに要求します。

  8. FactoryはServantのオブジェクトリファレンスを作成して、オブジェクトリファレンスをクライアントに通知します。

  9. クライアントアプリケーションはオペレーションop()を要求します。

  10. POAは、AOMを検索するが、未登録の要求であるためServantManagerを呼び出します。

  11. ServantManagerは該当するServantを検索して返します。

  12. POAはServantManagerからServantを受け取り、AOMに登録します。

  13. POAはServantに対してオペレーションop()の実行を依頼します。

  14. POAはオペレーションop()の結果をクライアントに通知します。


(4)ユーザインスタンス管理方式

  インスタンス管理をユーザの作成するServantManagerオブジェクトに任せる方式です。



  1. OD_or_admコマンドで事前にFactoryのオブジェクトリファレンスをNamingServiceに登録します。

  2. サーバアプリケーションはFactoryを作成します。

  3. サーバアプリケーションはFactoryをDefault ServantとしてPOAに登録します。

  4. サーバアプリケーションはServantManagerを作成します。

  5. サーバアプリケーションはServantManagerをPOAに登録します。

  6. クライアントアプリケーションはNamingServiceからFactoryのオブジェクトリファレンスを獲得します。

  7. クライアントアプリケーションはオペレーションcreateをFactoryに要求します。

  8. FactoryはServantのオブジェクトリファレンスを作成して、オブジェクトリファレンスをクライアントに通知します。

  9. クライアントアプリケーションはオペレーションop()を要求します。

  10. POAは、ServantManagerのpreinvoke()を呼び出します。

  11. ServantManagerはServantのインスタンスを検索して、POAに通知します。

  12. POAは獲得したインスタンスでServantに対してオペレーションop()の実行を依頼します。

  13. POAはオペレーションop()の結果をクライアントに通知します。

  14. POAは ServantManagerのpostinvoke()を呼び出します。


4.3.1.3 アプリケーション形態の比較

  

デフォルトインスタンス方式

Factory-1方式

Factory-2方式

ユーザインスタンス管理方式

インスタンス管理

しない

する

する

する

インスタンス管理者

POAオブジェクト

POAオブジェクト

ユーザが作成したServantManagerオブジェクト

性能

優れている

Factory-2方式より優れる

Factory-1方式より劣る

ユーザアプリによる

資源

少ない

Factory-2方式より多い

Factory-1方式より少ない

ユーザアプリによる

開発の難易度

やさしい

普通

普通

難しい