POA (Portable Object Adapter)は、CORBA2.2で新しく標準的なオブジェクトアダプタとして採用された仕様です。POAとしてオブジェクトアダプタの仕様が明確化されたことにより、ORB製品ごとの仕様上の差違が排除されるため、異なるORB製品へのサーバアプリケーションの移植が容易となります。
POAの特徴
POAオブジェクト内にAOM(Active Object Map:インスタンスの管理テーブル)を持ち、インスタンス管理を行います。サーバアプリケーションは、以下の2とおりのインスタンス管理を行うことが可能です。
サーバアプリケーションは、事前にインスタンスを作成してAOMに登録しておきます。クライアントからのリクエスト受信時に、AOMのインスタンスが検索され、Servantオブジェクトが実行されます。
クライアントからのリクエスト受信時に、POAオブジェクトはユーザ実装のServantManagerを呼び出します。ServantManagerでは、インスタンスを作成してAOMに登録します。次に、Servantオブジェクトが実行されます。
POAに対してポリシを設定することで、POAごとにインスタンス管理方法、オブジェクトの生存期間、多重動作などのポリシを指定できます。POAポリシとして、以下の種類があります。
詳細については、“4.3.2.3 POAオブジェクト”を参照してください。
Servant関連付けポリシ: ServantRetentionPolicy
リクエスト処理ポリシ: RequestProcessingPolicy
暗黙的活性化ポリシ: ImplicitActivationPolicy
ID割り当てポリシ: IdAssignmentPolicy
オブジェクトID一意性ポリシ: IdUniquenessPolicy
生存期間ポリシ: LifespanPolicy
スレッドポリシ: ThreadPolicy
POAは、以下のような仕組みを提供します。
POAオブジェクトは、オブジェクトID、Servantオブジェクト(ユーザ提供のサーバ実装のインスタンス)の関係をAOM(Active Object Map)上で管理し、クライアントからの要求メッセージに従って、Servantオブジェクトのメソッドを実行します。
POAの要求メッセージ処理の受付けに関する状態を制御します。
サーバアプリケーションが提供するインタフェースを実装し、リクエストに対する処理を実際に行う、ユーザ作成のオブジェクトを示します。
Default Servantオブジェクトは、RequestProcessingポリシにUSE_DEFAULT_SERVANTが設定されています。さらに、リクエストに対応するServantオブジェクトがPOAのAOM(Active Object Map)に存在しない場合に、POAはDefault Servantオブジェクトのメソッドを実行します。
ServantManagerオブジェクトはPOAオブジェクトにより呼び出され、Servantオブジェクトの作成および検索を行います。
ServantManagerオブジェクトは、RequestProcessingポリシにUSE_SERVANT_MANAGERが設定されている場合にPOAオブジェクトが呼び出しますが、以下の2種類があります。
ServantActivator(ServantRetentionポリシがRETAINの場合)
POAオブジェクトは、POAオブジェクトのAOM(ActiveObjectMap)に、リクエストに対応するServantオブジェクトが存在しない場合に、ServantActivatorオブジェクトにServantオブジェクトの生成を要求します。ServantActivatorオブジェクトはServantオブジェクトを返し、POAオブジェクトはServantオブジェクトのメソッドを実行します。
このServantActivatorオブジェクトは、ユーザが作成する必要があります。
ServantLocator(ServantRetentionポリシがNON_RETAINの場合)
POAオブジェクトは、リクエスト受信時、ServantLocatorオブジェクトに対応するServantオブジェクトを問い合わせます。ServantLocator オブジェクトはServantオブジェクトを返し、POAオブジェクトはServantオブジェクトのメソッドを実行します。
このServantLocatorオブジェクトは、ユーザが作成する必要があります。また、対応するServantオブジェクトを管理する必要があります。
詳細については、“4.3.2.10 ServantManagerオブジェクト”を参照してください。
リクエストの受信時、対応するPOAオブジェクトが存在しない場合に、POAオブジェクトを生成します。
このAdapterActivatorオブジェクトは、ユーザが作成する必要があります。
オブジェクトIDは、POAオブジェクトが対応するServantオブジェクトを特定するための値です。オブジェクトIDの値は、IdAssignmentポリシによって、POAオブジェクトによって割り当てられる場合と、ユーザアプリケーションにより割り当てられる場合があります。オブジェクトIDは、オブジェクトリファレンス中に含められるため、クライアントから意識する必要はありません。
POA IDは、リクエストの受信時にPOAオブジェクトを特定するための値です。POA IDは、オブジェクトリファレンス中に含められるため、クライアントから意識する必要はありません。
POAオブジェクトの作成時に、以下のPOAポリシを設定できます。
POAポリシ | 意味 | Value | Valueの説明 | 備考 |
---|---|---|---|---|
ServantRetention: | AOMテーブルをPOAオブジェクト内で持つか持たないかを指定します。つまり、POAオブジェクト内でインスタンス管理を行うかどうかを指定できます。 “4.3.2.7 リクエスト処理”参照。 | RETAIN (注1) | ActiveObjectMapにActiveなServantオブジェクトを憶えます。 |
|
NON_RETAIN | ActiveObjectMapを使いません。 | |||
RequestProcessing: | リクエスト受信時に対象インスタンスをAOM内に持ってない、もしくはAOM自身を保持しないときの振る舞いを規定するポリシです。 “4.3.2.7 リクエスト処理”参照。 | USE_ACTIVE_ | リクエスト処理にActiveObjectMapだけ使用します。 |
|
USE_DEFAULT_ | リクエストの処理をDefault Servantオブジェクトに任せます。 | |||
USE_SERVANT_ | ServantManagerオブジェクトによって目的のServantオブジェクトを見つけます。必要であればactivateも行われます。 | |||
ImplicitActivation: | Servantの活性化のモードを以下のように指定可能です。
| IMPLICIT_ | 自動的にServantオブジェクトがactivateされます。 |
|
NO_IMPLICIT_ | 自動的にServantオブジェクトがactivateされません(サーバアプリケーションが明示的にServantオブジェクトを生成して、POAオブジェクトに登録します)。 | |||
IdAssignment: | オブジェクトIDをシステム(POAオブジェクト)が自動設定するか、ユーザが設定するかを指定できます。 “4.3.2.6 オブジェクトの活性化”参照。 | SYSTEM_ID (注1) | POAオブジェクトがオブジェクトIDを付けます。 |
|
USER_ID | ユーザがオブジェクトIDを付けます。 | |||
IdUniqueness: | ServantにユニークなIDを付けるか、重複したIDを許すかを指定できます。 | UNIQUE_ID (注1) | ServantオブジェクトにユニークなIDを付けます。 |
|
MULTIPLE_ID | Servantオブジェクトに重複したIDを許します。 | |||
Lifespan: | トランジェントタイプのオブジェクトを扱うかパーシステントタイプのオブジェクトを扱うかを指定可能です。 | TRANSIENT (注1) | トランジェントタイプのオブジェクトを扱います(サーバlifespan = オブジェクトlifespan)。 | PERSISTENTは、指定不可 |
PERSISTENT | パーシステントタイプのオブジェクトを扱います(サーバlifespan < オブジェクトlifespan)。 | |||
Thread: | スレッド処理をORBに任せるかシングルスレッドで動作させるかを指定できます。 | ORB_CTRL_MODEL (注1) | スレッド処理をORBに任せます。 | このPOAポリシの設定値は、無効(注2) |
SINGLE_THREAD_ | シングルスレッドで動作させます。 |
注1)デフォルト値
注2)インプリメンテーションリポジトリ登録時のプロセス最大多重度(proc_conc_max)、スレッド初期多重度(thr_conc_init)の設定内容に依存します。
POAポリシの生成例を以下に示します。
例
// POAポリシリスト作成 CORBA::PolicyList policies( 4 ); // POAのポリシリスト CORBA::Environment env; // 例外情報 policies.length( 4 ); policies[0] = Poa->create_servant_retention_policy( PortableServer::NON_RETAIN, env ); policies[1] = Poa->create_request_processing_policy( PortableServer::USE_DEFAULT_SERVANT, env ); policies[2] = Poa->create_id_assignment_policy( PortableServer::SYSTEM_ID, env ); policies[3] = Poa->create_id_uniqueness_policy( PortableServer::MULTIPLE_ID, env );
注) ソース内のPoa:POAクラスのインスタンス
POAオブジェクトの生成
POAオブジェクトを使用するためには、まずRootPOAオブジェクトを生成する必要があります。POAオブジェクトは、RootPOAオブジェクトをルートとして、子POAオブジェクトや孫POAオブジェクトを生成することでツリー構成とすることができます。RootPOAオブジェクトは、ORBがサーバの初期化時に生成します。RootPOAオブジェクトのPOAオブジェクトは、以下のように取得できます。
例
main( int argc, char* argv[] )
{
CORBA::ORB_ptr orb; // ORBのオブジェクトリフレンス
CORBA::Object_ptr obj; // オブジェクトリファレンスの格納域
CORBA::Environment env; // 例外情報
int current_argc = argc;
// ORBの生成と初期化
orb = CORBA::ORB_init( current_argc, argv, FJ_OM_ORBid, env );
// RootPOAオブジェクトのオブジェクトリファレンスの取得
obj = orb->resolve_initial_references("RootPOA", env );
// RootPOAオブジェクトのPOAオブジェクト獲得
PortableServer::POA_ptr rootPOA =
PortableServer::POA::_narrow( obj );
RootPOAオブジェクトには、以下のPOAポリシが設定されています。
ServantRetentionPolicy: RETAIN
RequestProcessingPolicy: USE_ACTIVE_OBJECT_MAP_ONLY
ImplicitActivationPolicy: IMPLICIT_ACTIVATION
IdAssignmentPolicy: SYSTEM_ID
IdUniquenessPolicy: UNIQUE_ID
LifespanPolicy: TRANSIENT
ThreadPolicy: ORB_CTRL_MODEL
ユーザアプリケーションで上記のPOAポリシを使用してインスタンス管理を行う場合は、RootPOAオブジェクトをそのまま使用することが可能です。しかし、新しいPOAオブジェクト(RootPOAオブジェクトの子孫POAオブジェクト)を生成し、固有のPOAポリシを設定することによりRootPOAオブジェクトとは異なるPOAポリシでインスタンス管理を行うことが可能となります。
新しいPOAオブジェクトを生成するには、すでに存在するPOAオブジェクト上でcreate_POA()メソッドを呼び出します。この結果、create_POA()を発行したPOAオブジェクトと新しく生成されたPOAオブジェクトは親子関係となります。アプリケーションで最初に生成するPOAオブジェクトはRootPOAオブジェクトであるため、その他のPOAオブジェクトはすべてRootPOAオブジェクトの子孫POAオブジェクトとなります。
create_POA()の引数としてPOAポリシリスト(Policyクラスの配列)を渡すことで、生成した子POAオブジェクトのポリシを設定することが可能です。
例
// 子POAオブジェクト(childPOA1)の生成 PortableServer::POA_ptr childPOA1 = rootPOA->create_POA( "poa_1", poamanager, policies1 ); // 孫POAオブジェクト(childPOA2)の生成 PortableServer::POA_ptr childPOA2 = childPOA1->create_POA("poa_2", poamanager, policies2 );
注)ソース内のpoa_1,poa_2:生成するPOAの名前
ソース内のpoamanager:POAManagerクラスのインスタンス
policies1/policies2:Policyクラスのインスタンス
上記のように、POAオブジェクトは階層構造をもたせることが可能です。オブジェクトの生成、オブジェクトと管理するPOAオブジェクトとの関係については、“4.3.3 サーバアプリケーションと環境設定との関連付け”を参照してください。destroy()メソッドによりあるPOAオブジェクトが破棄された場合、その子孫POAオブジェクトはすべて破棄されます。
POAポリシの設定値の組合せ
ポリシリストに設定したPOAポリシの各設定値は、create_POA()メソッド発行時にそれらの組合せが妥当であるかチェックされます。もし、設定値の組合せが妥当でない場合は、例外が発生します。
以下にPOAポリシの設定値の組合せを示します。妥当性欄で“*”の部分はこの値が設定された場合、create_POA()メソッド実行時にPortableServer::POA::InvalidPolicy例外が発生することを示しています。
なお、LifespanPolicyの設定値は、TRANSIENTとしてください。また、ThreadPolicyの設定値は、無視されます。
ポリシ | Servant | Request | Implicit | IdAssignment | IdUniqueness | 妥当性 |
---|---|---|---|---|---|---|
設定値 | RETAIN | USE_ACTIVE_ | IMPLICIT_ | SYSTEM_ID | UNIQUE_ID |
|
MULTIPLE_ID |
| |||||
USER_ID | - | * | ||||
NO_IMPLICIT_ | SYSTEM_ID | UNIQUE_ID |
| |||
MULTIPLE_ID |
| |||||
USER_ID | UNIQUE_ID |
| ||||
MULTIPLE_ID |
| |||||
USE_DEFAULT_ | IMPLICIT_ | SYSTEM_ID | UNIQUE_ID | * | ||
MULTIPLE_ID |
| |||||
USER_ID | - | * | ||||
NO_IMPLICIT_ | SYSTEM_ID | UNIQUE_ID | * | |||
MULTIPLE_ID |
| |||||
USER_ID | UNIQUE_ID | * | ||||
MULTIPLE_ID |
| |||||
USE_SERVANT_ | IMPLICIT_ | SYSTEM_ID | UNIQUE_ID |
| ||
MULTIPLE_ID |
| |||||
USER_ID | - | * | ||||
NO_IMPLICIT_ | SYSTEM_ID | UNIQUE_ID |
| |||
MULTIPLE_ID |
| |||||
USER_ID | UNIQUE_ID |
| ||||
MULTIPLE_ID |
| |||||
NON_RETAIN | USE_ACTIVE_ | - | - | - | * | |
USE_DEFAULT_ | - | SYSTEM_ID | UNIQUE_ID | * | ||
MULTIPLE_ID |
| |||||
USER_ID | UNIQUE_ID | * | ||||
MULTIPLE_ID |
| |||||
USE_SERVANT_ | - | SYSTEM_ID | UNIQUE_ID |
| ||
MULTIPLE_ID |
| |||||
USER_ID | UNIQUE_ID |
| ||||
MULTIPLE_ID |
|
注) ServantRetentionPolicyにNON_RETAINが設定されている場合、ImplicitActivationPolicyの設定値は無視されます。
POAポリシのデフォルト設定値
POAは、デフォルトのポリシ設定値として以下の値を持っています。
ポリシ | デフォルト値 |
---|---|
ServantRetention | RETAIN |
RequestProcessing | USE_ACTIVE_OBJECT_MAP_ONLY |
ImplicitActivation | NO_IMPLICIT_ACTIVATION |
IdAssignment | SYSTEM_ID |
IdUniqueness | UNIQUE_ID |
Lifespan | TRANSIENT |
Thread | ORB_CTRL_MODEL |
create_POA()メソッドを使用して新しいPOAを生成する際は、デフォルトの設定値から変更したいポリシだけ設定することが可能です。
以下の例では、USE_DEFAULT_SERVANTにRequestProcessingPolicyを、MULTIPLE_IDにIdUniquenessPolicyを設定した子POAを生成しています。この場合、他のポリシの設定値は、上記のデフォルトの設定値のままとなります。
例
CORBA::Environment env; // 例外情報 // POAポリシリスト作成 CORBA::PolicyList policies( 2 ) policies[0] = Poa->create_request_processing_policy( PortableServer::USE_DEFAULT_SERVANT, env ); policies[1] = Poa->create_id_uniqueness_policy( PortableServer::MULTIPLE_ID, env ); // 子POAオブジェクトの生成 PortableServer::POA_ptr Poa1 = Poa->create_POA( "poa_1", poamanager, policies );
注)ソース内のPoaは:POAクラスのインスタンス
ソース内のpoamanager:POAManagerクラスのインスタンス
なお、create_POA()メソッドの第3パラメタにnullを指定した場合は、生成される子POAのポリシはデフォルトの設定値となります。
オブジェクトリファレンスは、以下の方法で生成します。
Servantオブジェクトの活性化前に作成する方法(直接作成)
サーバアプリケーションは、直接オブジェクトリファレンスをPOAオブジェクトのcreate_reference()やcreate_reference_with_id()メソッドで作成できます。この操作は、オブジェクトリファレンスだけを作成します。実際のアクティブなServantオブジェクトは、後からServantManagerオブジェクトで生成される場合もあります。
例
CORBA::Environment env; // 例外情報 // オブジェクトリファレンスの生成 CORBA::Object _bind_obj = Poa->create_reference( "IDL:Intfid11:1.0", env ); // ID指定によるオブジェクトリファレンスの生成 long len = strlen( "USERID" ); CORBA::Octet* buf = PortableServer::ObjectId::allocbuf( len ); memcpy( buf, "USERID", len ); PortableServer::ObjectId_var userid = new PortableServer::ObjectId( len, len, buf, CORBA_TRUE ); CORBA::Object _bind_obj = Poa->create_reference_with_id( *userid, "IDL:Intfid11:1.0", env );
注)ソース内のPoa:POAクラスのインスタンス
IDL:Intfid11:1.0:インタフェースリポジトリID
Servantオブジェクトの活性化後に作成する方法(間接作成)
サーバアプリケーションは、activate_object()/activate_object_with_id()メソッドよりServantオブジェクトを活性化します。一度Servantオブジェクトが活性化されると、サーバアプリケーションはServantオブジェクト/オブジェクトIDを指定して、servant_to_reference()/id_to_reference()メソッドを発行することにより容易にオブジェクトリファレンスを作成できます。また、POAオブジェクトがIMPLICIT_ACTIVATIONポリシで作成されていれば、servant_to_reference()を使用してオブジェクトリファレンスを生成した場合、自動的にServantオブジェクトがactivateされ、オブジェクトリファレンスが有効となります。
例
// Servantの生成 ODsample_intf_impl* svt = new ODsample_intf_impl(); // IMPLICIT_ACTIVATIONポリシを指定している場合、自動的にactivateされる CORBA::Object_ptr obj = Poa->servant_to_reference( svt, env );
注) ソース内のPoaオブジェクト:POAクラスのインスタンス
一度オブジェクトリファレンスがクライアントに通知されると、クライアントの側から見るとそのオブジェクトリファレンスはオブジェクトの身元を持っていることになります。クライアントプログラムがそのオブジェクトリファレンスを使う限り、そのオブジェクトリファレンスで作られるリクエストは同一のオブジェクトのインスタンスに送信されます。
オブジェクトリファレンス、オブジェクトID(oid)、Servantオブジェクトの関係は、IdUniquenessPolicyによって決まります。オブジェクトリファレンスは、oidを包含しているため、referenceとoidは、1対1の関係となります。oidとServantオブジェクトの関係は、UNIQUE_IDの場合では、Servantオブジェクトごとに一意のoidが割り当てられます。MULTIPLE_IDの場合は、同じServantオブジェクトへの複数のoidが割り当て可能です。このことは、具体的にはoidを生成するservant_to_id()/servant_to_reference()の動作に影響を与えます。
オブジェクトが活性状態とは、POAオブジェクトの管理するAOM(Active Object Map)に、あるServantオブジェクトがオブジェクトIDと関連付けられて登録されている状態のことを指します。
Servantオブジェクトは、インスタンスとして生成されただけでは、POAオブジェクトに認識されないため、activate_object()/activate_object_with_id()メソッドを使用して、オブジェクトIDとの関連付けをPOAオブジェクトに登録する必要があります。Servantオブジェクトを活性化する方法を以下に示します。
明示的にServantオブジェクトを活性化する方法
Servantオブジェクトの作成(new)後に、activate_object()/activate_object_with_id()メソッドでAOMに登録できます。
例
CORBA::Environment env; // 例外情報 // Servantの生成 ODsample_intf_impl* svt = new ODsample_intf_impl(); // Servantの活性化 Poa->activate_object ( svt, env ); // ID指定によるServantの活性化 long len = strlen( "USERID" ); CORBA::Octet* buf = PortableServer::ObjectId::allocbuf( len ); memcpy( buf, "USERID", len ); PortableServer::ObjectId_var userid = new PortableServer::ObjectId( len, len, buf, CORBA_TRUE ); Poa->activate_object_with_id( *userid, svt, env );
注) ソース内のPoaオブジェクト:POAクラスのインスタンス
なお、活性化の際にはオブジェクトIDが必要となりますが、オブジェクトIDの割付けは、IdAssignmentPolicyに従って処理されます。
SYSTEM_IDの場合
POAオブジェクトが自動的にオブジェクトIDを割り付けます。Servantオブジェクトを活性化する場合に、activate_object()を使用してください。
USER_IDの場合
ユーザがオブジェクトIDを割り付けます。Servantオブジェクトを活性化する場合は、activate_object_with_id()を使用してください。
暗黙的にServantオブジェクトを活性化する方法
POAオブジェクトがIMPLICIT_ACTIVATIONポリシを持っている場合、servant_to_reference()メソッドを使用してリファレンスを生成すると、自動的にServantオブジェクトが活性化されて、オブジェクトリファレンスが通知されます。暗黙的活性化については、“4.3.2.8 暗黙的活性化(Implicit Activation)”を参照してください。
例
CORBA::Environment env; // 例外情報 // Servantの生成 ODsample_intf_impl* svt = new ODsample_intf_impl(); // IMPLICIT_ACTIVATIONポリシを指定している場合、自動的にactivateされる CORBA::Object Obj = Poa->servant_to_reference( svt, env );
注) ソース内のPoaオブジェクト:POAクラスのインスタンス
なお、暗黙的活性化の場合、オブジェクトIDはPOAオブジェクトにより自動的に割り付けます。このため、IdAssignmentPolicyは、SYSTEM_IDに設定しておく必要があります。
POAオブジェクトの検索
クライアントからのリクエスト受信時に、インタフェースリポジトリIDに対応するPOAオブジェクトがサーバプロセス上に存在しなければ、親のPOAオブジェクトはAdapterActivatorオブジェクトを呼び出します。AdapterActivatorオブジェクトでは、要求されたPOAオブジェクトを作成します。
AdapterActivatorオブジェクトは、ユーザが作成する必要があります。また、事前にPOAオブジェクトに登録しておく必要があります。もし、AdapterActivatorオブジェクトが登録されていない場合、クライアントはOBJECT_NOT_EXIST例外を受け取ります。
Servantオブジェクトの検索
クライアントからのリクエスト受信時に、POAオブジェクトはAOMに登録されているServantオブジェクトを検索します。なお、AOMを使用するかどうかは、対象のPOAオブジェクトがRETAINポリシ(使用する)とNON_RETAINポリシ(使用しない)のどちらが指定されているかによります。
RETAINポリシが指定され、目的のServantオブジェクトがAOM内にみつかった場合、検索処理はそこで終了してServantオブジェクトのメソッドを実行します。Servantオブジェクトがみつからなかった場合や、NON_RETAINの場合は、以下のRequestProcessingポリシに従って処理を行います。
USE_DEFAULT_SERVANT
対象のServantオブジェクトがみつからなかった場合、デフォルトのServantオブジェクトに処理を任せる方法です。この場合、あらかじめset_servant()によりデフォルトのServantオブジェクトを登録しておく必要があります。もし、Default Servantオブジェクトが登録されていなければ、OBJ_ADAPTERエラーとなります。
USE_SERVANT_MANAGER
対象のServantオブジェクトがみつからなかった場合、ServantManagerオブジェクトにServantオブジェクトを検索する処理を任せる方法です。
リクエストを扱えるServantオブジェクトを見つけるため、POAオブジェクトは、incarnate()/preinvoke()を呼び出します(メソッド選択は、POAオブジェクトのNON_RETAIN/RETAINポリシに依存します)。ServantManagerオブジェクトは、見つけたServantオブジェクトをPOAオブジェクトに通知します。この場合、あらかじめ、set_servant_manager()によりServantManagerオブジェクトを登録しておく必要があります。もし、ServantManagerオブジェクトが登録されていなければ、OBJ_ADAPTERエラーとなります。
USE_ACTIVE_OBJECT_MAP_ONLY
この場合、OBJECT_NOT_EXISTエラーとなります。
Servantオブジェクトの活性化方法には、アプリケーションが明示的にServantオブジェクトを活性化させる方法に加え、POAオブジェクトにより暗黙的(Implicit)にServantオブジェクトを活性化させるIMPLICIT_ACTIVATIONポリシがあります。
IMPLICIT_ACTIVATIONポリシを使用するためには、SYSTEM_IDポリシおよびRETAINポリシを指定する必要があります。IMPLICIT_ACTIVATIONポリシを指定することにより、servant_to_reference()/servant_to_id()などのServantオブジェクトからオブジェクトリファレンスやオブジェクトIDに変換するメソッドを使用した際に、POAオブジェクトがAOMにServantオブジェクトおよびオブジェクトIDを登録し、Servantオブジェクトを活性化できます。このときにUNIQUE_IDポリシが指定されていた場合、再度、servant_to_reference()/servant_to_id()を使用した場合、前回と同じリファレンスやオブジェクトIDが返されます。MULTIPLE_IDポリシが指定されていた場合、毎回、異なったオブジェクトリファレンスやオブジェクトIDが返されます。これは、同じServantオブジェクトに複数のオブジェクトリファレンスやオブジェクトIDが割り付けられることを意味します。
POAManagerオブジェクトは、POAオブジェクトの生成時、create_POA()メソッドの引数として渡すことにより、POAオブジェクトと関連付けられます。POAManagerは、以下の4つの状態を持っています。POAオブジェクトは、POAManagerの状態に従って処理を決定します。この状態は、activate()、hold_requests()、discard_requests()、deactivate()などのメソッドで変更できます。
受け取ったメッセージをキューイングします。
受け取ったメッセージを処理します。
受け取ったメッセージを捨てます。この場合、クライアントへはエラーが通知されます。
shutdown直前の状態。
POAオブジェクトの状態遷移を以下に示します。
ServantManagerオブジェクトは、リクエスト受信時に、Servantオブジェクトの生成/削除/検索を可能にする機能です。ServantManagerオブジェクトの各メソッドの実装は、ユーザ自身で作成します。作成したServantManagerオブジェクトは、POAオブジェクトに登録しておきます。
POAオブジェクトがリクエストを受信した際、AOMにオブジェクトIDが一致するServantオブジェクトが登録されていない場合、POAオブジェクトはServantManagerオブジェクトのメソッドを呼び出し、Servantオブジェクトの生成/削除/検索を依頼します。
ServantManagerオブジェクトは、以下のの2種類が存在します。
Servantオブジェクトの生成/削除を行うServantActivatorオブジェクト
Servantオブジェクトを検索するServantLocatorオブジェクト
POAオブジェクトは、以下のオブジェクトを呼び出します。
ServerRetentionポリシがRETAINの場合:ServantActivatorオブジェクト
ServerRetentionポリシがNON_RETAINの場合:ServantLocatorオブジェクト
作成するServantActivatorクラスは、以下のようにPortableServer::ServantActivatorクラスを継承させる必要があります。また、メソッドとしてincarnate()/etherealize()を実装している必要があります。
【ServantActivatorクラスの実装形式】
class UserServantActivator : public PortableServer::ServantActivator
{ public : PortableServer::Servant incarnate(...) {...} void etherealize(...) {...} };
POAオブジェクトは、以下のメソッドを呼び出します。
Servantオブジェクトの生成を依頼する場合:ServantActivatorオブジェクトのincarnate()メソッド
Servantオブジェクトの削除を依頼する場合:ServantActivatorオブジェクトのetherealize()メソッド
POAオブジェクトから渡されるパラメタは、必要に応じて各メソッドの実装部で使用できます。
incarnate (Servantオブジェクト生成)
POAは、リクエスト受信時にAOMに対象のServantオブジェクトが未登録の場合、incarnate()メソッドを呼び出します。incarnate()メソッドは、POAオブジェクトにServantオブジェクトを生成させ返します。
PortableServer::Servant incarnate( const PortableServer::ObjectId& oid, PortableServer::POA_ptr adapter, CORBA::Environment env )
oid:リクエスト対象のオブジェクトのオブジェクトID
adapter:呼び出し元のPOAオブジェクト
etherealize (Servantオブジェクト削除)
POAは、アプリケーションからdeactivate_object()メソッドが呼び出されたときに、etherealize()メソッドを呼び出します。POAオブジェクトが削除するServantオブジェクトをパラメタで指定します。etherealize()メソッドは、指定されたServantオブジェクトを削除します。
void etherealize( const PortableServer::ObjectId& oid, PortableServer::POA_ptr adapter, PortableServer::Servant serv, CORBA::Boolean cleanup_in_progress, CORBA::Boolean remaining_activations, CORBA::Environment env );
oid:削除対象のServantオブジェクトに対応するオブジェクトID
adapter:呼び出し元のPOAオブジェクト
serv:削除対象のServantオブジェクト
cleanup_in_progress:POA->destoroy()から本メソッドが呼ばれた場合にtrue
remaining_activations:本メソッド呼出し時、常にfalse
ServantActivatorオブジェクトの具体的な処理の流れを以下に示します。
FactoryにServantのオブジェクトリファレンスの生成を依頼します。(注)
Factoryで生成したオブジェクトリファレンスをクライアントに返します。
Servantに、オペレーションop()を要求します。
POAでは、AOMに未登録の要求であるため、ServantActivatorを呼び出します。
ServantActivatorでは、該当するServantを検索して返します。
ServantActivatorからServantを受け取り、AOMに登録します。
Servantに対してオペレーションop()の実行を依頼します。
クライアントに、オペレーションop()の結果を通知します。
注) Factoryは、リクエストごとにオブジェクトリファレンスやインスタンスを作成するオブジェクトです。インスタンス管理を行う場合に必要となるオブジェクトです。
作成するServantLocatorクラスは、以下のようにPortableServer::ServantLocatorクラスを継承させる必要があります。また、メソッドとしてpreinvoke()/postinvoke()を実装している必要があります。
【ServantLocatorクラスの実装形式】
class UserServantLocator : public PortableServer::ServantLocator
{ public : PortableServer::Servant preinvoke(...) {...} void postinvoke(...) {...} };
POAオブジェクトはクライアントからの要求を処理するため、毎回ServantLocatorオブジェクトのpreinvoke()メソッドを呼び出し、処理対象のServantオブジェクトを獲得します。POAオブジェクトはそのServantオブジェクトに処理を要求し、その処理が終わったら、ServantLocatorオブジェクトのpostinvoke()メソッドを呼び出し、ServantLocatorオブジェクトに後処理を依頼します。
POAオブジェクトから渡されるパラメタは、必要に応じて各メソッドの実装部で使用できます。
preinvoke
POAオブジェクトは、処理を要求すべきServantオブジェクトを獲得するために、ServantLocatorオブジェクトのpreinvoke()メソッドを呼び出します。preinvoke()メソッドは、POAオブジェクトにServantオブジェクトを返すと同時に、postinvoke()のための情報(cookie)も返します。
PortableServer::Servant preinvoke( const PortableServer::ObjectId oid, PortableServer::POA_ptr adapter, CORBA::Identifier operation, PortableServer::ServantLocator::Cookie the_cookie, CORBA::Environment& = CORBA::Environment() )
oid:リクエスト対象のオブジェクトのオブジェクトID
adapter:呼び出し元のPOAオブジェクト
operation:リクエスト対象のオペレーションの名前
the_cookie:Cookieオブジェクトを格納する
postinvoke
POAオブジェクトは、Servantオブジェクトの要求処理の終了直後に、ServantLocatorオブジェクトのpostinvoke()を呼び出します。このとき、preinvoke()との対応をとるため、preinvoke()で返されたcookieを指定します。
void postinvoke( const PortableServer::ObjectId oid, PortableServer::POA_ptr adapter, CORBA::Identifier operation, CORBA::Object the_cookie, PortableServer::Servant the_servant, CORBA::Environment& = CORBA::Environment() )
oid:リクエスト対象のオブジェクトのオブジェクトID
adapter:呼び出し元のPOAオブジェクト
operation:リクエスト対象のオペレーションの名前
the_cookie:preinvokeで返されたCookieオブジェクト
the_servant:リクエストに対する処理を行ったServantオブジェクト
ServantLocatorの具体的な処理の流れを以下に示します。
Factoryに、Servantのオブジェクトリファレンスの生成を依頼します。
Factoryで生成したオブジェクトリファレンスをクライアントに返します。
Servantに、オペレーションop()を要求します。
POAでは、ServantLocatorを呼び出します。
ServantLocatorのpreinvoke()でServantを検索します。
Servantを受け取ります。
Servantに対してオペレーションop()の実行を依頼します。
クライアントに、オペレーションop()の結果を通知します。
ServantLocatorのpostinvoke()を呼び出します。
クライアントへオペレーションを復帰します。
AdapterActivatorオブジェクトは、リクエストを受信時にPOAオブジェクトを生成するために使用します。POAオブジェクトが生成したオブジェクトリファレンスには、オブジェクトIDに加え、生成元POAオブジェクトを示すPOAidが埋め込まれています。クライアントからのリクエストが送られてきた際、POA idに対応するPOAオブジェクトが検索され、そのPOAオブジェクトがリクエストに対する処理を行います。もし、みつからない場合、検索対象のPOAの親POAオブジェクトにAdapterActivatorオブジェクトが設定されているならば、そのAdapterActivatorオブジェクトに子POAオブジェクトの生成を依頼します。親POAにAdapterActivatorオブジェクトが設定されていない場合は、CORBA::StExcep::OBJ_ADAPTER例外がクライアントに通知されます。
AdapterActivatorオブジェクトは、ユーザが作成し、POAに登録する必要があります。
作成するAdapterActivatorクラスは、PortableServer::AdapterActivatorクラスを継承させる必要があります。また、メソッドとしてunknown_adapter()を実装している必要があります。
【AdapterActivatorクラスの実装形式】
class UserAdapterActivator : public PortableServer::AdapterActivator { public : CORBA::Boolean unknown_adapter(...){...} }
unknown_adapter
POAidに対応するPOAが検出できなかった場合は、AdapterActivatorオブジェクトのunknown_adapter()メソッドが呼び出されます。unknown_adapter()には、パラメタとしてPOAオブジェクトとStringオブジェクトが渡されます。
unknown_adapter()内では、渡されたPOAオブジェクトの子POAをcreate_POA()を使用して生成します。このときのアダプタ名として、渡されたStringオブジェクトを使用します。
子POAに対するポリシ設定や、その他必要な処理(ServantやServantManagerの生成・登録など)もこのメソッド内に記述することが可能です。
子POAの生成およびその他の実装した処理が成功した場合は、戻り値としてtrueを返します。そうでない場合は、falseを返します。trueを返した場合は、生成した子POAからServantのオペレーションが起動されます。falseを返した場合は、CORBA::StExcep::OBJECT_NOT_EXIST例外がクライアントに通知されます。
CORBA::Boolean unknown_adapter( PortableServer::POA_ptr parent, CORBA::Char* name, CORBA::Environment& env );
parent:生成するPOAの親POA
name:生成するPOAのアダプタ名
AdapterActivatorオブジェクトのunknown_adapterメソッドは、PortableServer::POA::find_POAメソッド発行時に呼び出すことも可能です。
AdapterActivatorの処理の流れを以下に示します。
クライアントからのリクエストを受信します。リクエストの対象となるオブジェクトリファレンスは、POAidを内包しています。
POAidに対応するPOAオブジェクトを検索します。存在しない場合は、既存のPOAから対象のPOAの親POAを検索します。
親POAオブジェクトに設定されているAdapterActivatorクラスのインスタンスに対して、unknown_adapeter()メソッドが発行されます。
unknown_adapeter()の実装部では、パラメタで渡されたPOA(親POA)の子POAオブジェクトを生成します。以降、同じオブジェクトリファレンスに対するリクエストの処理は、このPOAが行います。
生成した子POAに対する設定などを行います。ここでは、直接Servantを生成して子POAに登録することも可能であり、ServantManagerを生成し登録しておくことも可能です。
子POAの生成に成功した場合は、trueを返します。
Servantの生成/登録を行います(ServantManager使用時)。
Servantのオペレーションを起動します。
オペレーションの実行結果を返します。