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

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方式より少ない

ユーザアプリによる

開発の難易度

やさしい

普通

普通

難しい