サーバアプリケーションは、Servant(インタフェース実装部)のインスタンスの管理方法により以下の4つの形態をとることができます。
以下のように要件によりアプリケーション形態を選択してください。
各クライアントが同一のServantオブジェクトを使用する方式です。つまり、クライアントごとのインスタンス管理をしない方式です。
各クライアントは、以下のように同一のServantのインスタンスを使用します。
クライアントごとに異なるServantオブジェクトを使用する方式です。
クライアントごとのインスタンス管理をPOAオブジェクトで行う方式です。Factory内で、オブジェクトリファレンスおよびインスタンスを作成します。
クライアントごとに異なる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インタフェースを定義します。
【FactoryのIDL定義例(a)】
// 何らかのインタフェース interface intf{ void op(); }; // Factoryインタフェース interface Factory { intf create(); };
上記のIDL定義で示されるように、クライアントはFactoryオブジェクトのオペレーションcreate()を発行することにより、そのクライアントで使用するintfオブジェクトを取得することが可能となります。
次に、クライアントは取得したintfオブジェクトに対してop()オペレーションを発行することで、本来の目的の処理を行います。
一方、サーバ側では、以下の一連の処理をcreate()オペレーションの実装として記述する必要があります。
Servantオブジェクト(intfインタフェースの実装クラスのインスタンス)を生成(new)します。
POAのAOMに生成したインスタンスとオブジェクトリファレンスとの関連付けを登録します。
関連付けられたオブジェクトリファレンスを返します。
Factory-2方式では、create()オペレーションの実装として3.のオブジェクトリファレンスの生成/復帰だけを行います。1.と2.は、要求時にServantManagerオブジェクト内で行います。しかし、クライアント側から見たcreate()オペレーションの機能は同じです。
Factoryとは、このようなインタフェースの機能上の概念です。したがって、IDL定義では、Factoryインタフェースの名前(上記の例の場合:“Factory”)、実装するオペレーションの名前(上記の例の場合:、“create”)、種類は、自由です。しかし、Factoryの目的上、上記のcreate()のような「戻り値としてオブジェクトリファレンスを返す」機能をもつオペレーションが最低限必要となります。
実際のアプリケーション開発では、生成したServantオブジェクトのインスタンスを解放するためのオペレーションもFactoryに実装することが推奨されます。これによりサーバ資源の節約が可能となります。
以下のIDL定義の例では、Servantオブジェクトのインスタンスを解放するためのオペレーションとしてdestroy()を定義しています。
【FactoryのIDL定義例(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ポリシ)としています。
これは、以下の理由によるものです。
同一のPOAのAOM上で、FactoryオブジェクトとそのFactoryが生成するServantオブジェクトを管理させることは可能です。しかし、この場合、Factoryオブジェクトへの要求に対してもAOM内の検索が行われるため、効率的ではありません。
Servantオブジェクトを管理するPOAのDefault ServantとしてFactoryオブジェクトを登録することは可能です。しかし、AOMとDefault Servantを同時に使用する場合は、Default Servantへの要求はAOMの検索の後となります。このため、Factoryオブジェクトへの要求は、効率的ではありません。
クライアントごとのインスタンス管理をしない方式です。
OD_or_admコマンドにより事前にServantのオブジェクトリファレンスをNamingServiceに登録します。
サーバアプリケーションは、Servantを作成します。
サーバアプリケーションは、ServantをPOAにDefault Servantとして登録します。
クライアントアプリケーションは、NamingServiceからオブジェクトリファレンスを獲得します。
クライアントアプリケーションは、オペレーションop()を要求します。
POAは、登録されているDefault Servantを起動します。
POAは、オペレーションop()の結果をクライアントに通知します。
クライアントごとでインスタンス管理をPOAオブジェクトで行う方式です。Factory内で、オブジェクトリファレンスおよびインスタンスを作成します。
OD_or_admコマンドで事前にFactoryのオブジェクトリファレンスをNamingServiceに登録します。
サーバアプリケーションは、Factoryを作成します。
サーバアプリケーションは、FactoryをDefault ServantとしてPOAに登録します。
クライアントアプリケーションは、NamingServiceからFactoryのオブジェクトリファレンスを獲得します。
クライアントアプリケーションは、オペレーションcreateをFactoryに要求します。
Factoryは、Servantのインスタンスを作成します。
Factoryは、AOMにインスタンスを登録します。
Factoryは、オブジェクトリファレンスを作成してクライアントに通知します。
クライアントアプリケーションは、オペレーションop()を要求します。
POAは、AOMを検索して、獲得したインスタンスでServantに対してオペレーションop()の実行を依頼します。
POAは、オペレーションop()の結果をクライアントに通知します。
クライアントごとでインスタンス管理をPOAオブジェクトで行う方式です。Factory内でオブジェクトリファレンスを作成し、リクエスト受信時にServantManagerオブジェクト内でインスタンスを作成します。
OD_or_admコマンドで事前にFactoryのオブジェクトリファレンスをNamingServiceに登録します。
サーバアプリケーションは、Factoryを作成します。
サーバアプリケーションは、FactoryをDefault ServantとしてPOAに登録します。
サーバアプリケーションは、ServantManagerを作成します。
サーバアプリケーションは、ServantManagerをPOAに登録します。
クライアントアプリケーションは、NamingServiceからFactoryのオブジェクトリファレンスを獲得します。
クライアントアプリケーションは、オペレーションcreateをFactoryに要求します。
Factoryは、Servantのオブジェクトリファレンスを作成して、オブジェクトリファレンスをクライアントに通知します。
クライアントアプリケーションは、オペレーションop()を要求します。
POAはAOMを検索するが、未登録の要求であるため、ServantManagerを呼び出します。
ServantManagerは、該当するServantを検索して返します。
POAは、ServantManagerからServantを受け取り、AOMに登録します。
POAは、Servantに対してオペレーションop()の実行を依頼します。
POAは、オペレーションop()の結果をクライアントに通知します。
インスタンス管理をユーザの作成するServantManagerオブジェクトに任せる方式です。
OD_or_admコマンドで事前にFactoryのオブジェクトリファレンスをNamingServiceに登録します。
サーバアプリケーションは、Factoryを作成します。
サーバアプリケーションは、FactoryをDefault ServantとしてPOAに登録します。
サーバアプリケーションは、ServantManagerを作成します。
サーバアプリケーションは、ServantManagerをPOAに登録します。
クライアントアプリケーションは、NamingServiceからFactoryのオブジェクトリファレンスを獲得します。
クライアントアプリケーションは、オペレーションcreateをFactoryに要求します。
FactoryはServantのオブジェクトリファレンスを作成して、オブジェクトリファレンスをクライアントに通知します。
クライアントアプリケーションは、オペレーションop()を要求します。
POAは、ServantManagerのpreinvoke()を呼び出します。
ServantManagerは、Servantのインスタンスを検索して、POAに通知します。
POAは、獲得したインスタンスでServantに対してオペレーションop()の実行を依頼します。
POAは、オペレーションop()の結果をクライアントに通知します。
POAは、ServantManagerのpostinvoke()を呼び出します。
| デフォルトインスタンス方式 | Factory-1方式 | Factory-2方式 | ユーザインスタンス管理方式 |
---|---|---|---|---|
インスタンス管理 | しない | する | する | する |
インスタンス管理者 | ― | POAオブジェクト | POAオブジェクト | ユーザが作成したServantManagerオブジェクト |
性能 | 優れている | Factory-2方式より優れる | Factory-1方式より劣る | ユーザアプリによる |
資源 | 少ない | Factory-2方式より多い | Factory-1方式より少ない | ユーザアプリによる |
開発の難易度 | やさしい | 普通 | 普通 | 難しい |