7.5.1 ServantActivator
- C++の場合
-
ServantActivatorは,ServantRetentionPolicy::RETAINとRequestProcessingPolicy::USE_SERVANT_MANAGERが設定された場合に使用します。
- Javaの場合
-
ServantActivatorは,ServantRetentionPolicy.RETAINとRequestProcessingPolicy.USE_SERVANT_MANAGERが設定された場合に使用します。
このタイプのサーバントマネージャによって活性化されたサーバントは,アクティブオブジェクトマップで管理されます。
サーバントアクティベータを使用したリクエストの処理中には,次のようなイベントが発生します。
-
クライアントリクエストを受信します(クライアントリクエストにはPOA名,オブジェクトIDなどの情報が含まれます)。
-
POAはまず,アクティブオブジェクトマップをチェックします。オブジェクトIDがそこで見つかれば,オペレーションはサーバントに渡され,クライアントに応答が返されます。
-
アクティブオブジェクトマップにオブジェクトIDが見つからなければ,POAはサーバントマネージャのincarnateを呼び出します。incarnateはオブジェクトIDと,オブジェクトを活性化しているPOAを渡します。
-
サーバントマネージャは適切なサーバントを探します。
-
サーバントIDがアクティブオブジェクトマップに入力され,クライアントに応答が返されます。
- 注
-
etherealizeおよびincarnateメソッドインプリメンテーションはユーザが指定するコードです。
そのあとで,サーバントを非活性化できます。これは,deactivate_objectオペレーション,該当するPOAと対応するPOAマネージャの非活性化など,幾つかのソースから行えます。オブジェクトの非活性化の詳細については,「7.4.5 オブジェクトの非活性化」を参照してください。
- コードサンプル7-13 サーバントアクティベータタイプのサーバントマネージャを示すサーバコードサンプル(C++)
int main(int argc, char* const* argv) { try { // Initialize the ORB. CORBA::ORB_ptr orb = CORBA::ORB_init(argc, argv); DataStore::_create(); // get a reference to the rootPOA CORBA::Object_var obj = orb->resolve_initial_references("RootPOA"); PortableServer::POA_var rootPOA = PortableServer::POA::_narrow(obj); CORBA::PolicyList policies; policies.length(2); policies[(CORBA::ULong)0] = rootPOA->create_lifespan_policy (PortableServer::PERSISTENT); policies[(CORBA::ULong)1] = rootPOA->create_request_processing_policy( PortableServer::USE_SERVANT_MANAGER); // Create myPOA with the right policies PortableServer::POAManager_var rootManager = rootPOA->the_POAManager(); PortableServer::POA_var myPOA = rootPOA->create_POA("bank_servant_activator_poa", rootManager, policies); // Create a Servant activator AccountManagerActivator servant_activator_impl; //Set the servant activator myPOA->set_servant_manager(&servant_activator_impl); // Generate two references - one for checking and another //for savings.Note that we are not creating any //servants here and just manufacturing a reference which //is not yet backed by a servant PortableServer::ObjectId_var an_oid = PortableServer::string_to_ObjectId ("CheckingAccountManager"); CORBA::Object_var cref = myPOA->create_reference_with_id (an_oid.in(), IDL:Bank/AccountManager:1.0"); an_oid = PortableServer::string_to_ObjectId ("SavingsAccountManager"); CORBA::Object_var sref = myPOA->create_reference_with_id (an_oid.in(), "IDL:Bank/AccountManager:1.0"); //Activate the POA Manager rootManager->activate(); // Write out Checking reference CORBA::String_var string_ref = orb->object_to_string (cref.in()); ofstream crefFile("cref.dat"); crefFile << string_ref << endl; crefFile.close(); // Now write out the Savings reference string_ref = orb->object_to_string(sref.in()); ofstream srefFile("sref.dat"); srefFile << string_ref << endl; srefFile.close(); // Waiting for incoming requests cout << "BankManager Server is ready" << endl; orb->run(); DataStore::_destroy(); } catch(const CORBA::Exception& e) { cerr << e << endl; } return 1; }
- コードサンプル7-14 サーバントアクティベータタイプのサーバントマネージャを示すサーバコードサンプル(Java)
import org.omg.PortableServer.*; public class Server { public static void main(String[ ] args) { try { // Initialize the ORB. org.omg.CORBA.ORB orb = org.omg.CORBA.FORB.init(args, null); // get a reference to the rootPOA POA rootPOA = POAHelper.narrow( orb.resolve_initial_references("RootPOA")); // Create policies for our POA. // We need persistence life span and // use servant manager request processing policies org.omg.CORBA.Policy[ ] policies = { rootPOA.create_lifespan_policy( LifespanPolicyValue.PERSISTENT), rootPOA.create_request_processing_policy( RequestProcessingPolicyValue. USE_SERVANT_MANAGER) }; // Create myPOA with the right policies POA myPOA = rootPOA.create_POA( "bank_servant_activator_poa", rootPOA.the_POAManager(), policies ); // Create the servant activator servant // and get its reference ServantActivator sa = new AccountManagerActivator()._this(orb); // Set the servant activator on our POA myPOA.set_servant_manager(sa); org.omg.CORBA.Object ref; // Activate the POA manager rootPOA.the_POAManager().activate(); // Generate the reference and write it out. // One for each Checking and Savings // account types .Note that we are not creating // any servants here and just manufacturing a // reference which is not yet backed by a servant. try { ref = myPOA.create_reference_with_id( "CheckingAccountManager".getBytes(), "IDL:Bank/AccountManager:1.0"); // Write out checking object ID java.io.PrintWriter pw = new java.io.PrintWriter( new java.io.FileWriter("cref.dat")); pw.println(orb.object_to_string(ref)); pw.close(); ref = myPOA.create_reference_with_id( "SavingsAccountManager".getBytes(), "IDL:Bank/AccountManager:1.0"); // Write out savings object ID pw = new java.io.PrintWriter( new java.io.FileWriter("sref.dat")); System.gc(); pw.println(orb.object_to_string(ref)); pw.close(); } catch ( java.io.IOException e ) { System.out.println( "Error writing the IOR to file "); return; } System.out.println("Bank Manager is ready."); // Wait for incoming requests orb.run(); } catch (Exception e) { e.printStackTrace(); } } }
このサンプルのサーバントマネージャを,次に示します。
- コードサンプル7-15 サーバントアクティベータのサンプルのサーバントマネージャ(C++)
// Servant Activator class AccountManagerActivator : public PortableServer::ServantActivator { public: virtual PortableServer::Servant incarnate (const PortableServer::ObjectId& oid, PortableServer::POA_ptr poa) { CORBA::String_var s = PortableServer::ObjectId_to_string (oid); cout << "\nAccountManagerActivator.incarnate called with ID = " << s << endl; PortableServer::Servant servant; if ( VISPortable::vstricmp( (char *)s, "SavingsAccountManager" ) == 0 ) //Create CheckingAccountManager Servant servant = new SavingsAccountManagerImpl; else if ( VISPortable::vstricmp( (char *)s, "CheckingAccountManager" ) == 0 ) //Create CheckingAccountManager Servant servant = new CheckingAccountManagerImpl; else throw CORBA::OBJECT_NOT_EXIST(); // Create a deactivator thread new DeActivatorThread( oid, poa ); // return the servant return servant; } virtual void etherealize ( const PortableServer::ObjectId& oid, PortableServer::POA_ptr adapter, PortableServer::Servant servant, CORBA::Boolean cleanup_in_progress, CORBA::Boolean remaining_activations) { // If there are no remaining activations i.e ObjectIds // associated with the servant delete it. CORBA::String_var s = PortableServer::ObjectId_to_string (oid); cout << "\nAccountManagerActivator.etherealize called with ID = " << s << endl; if (!remaining_activations) delete servant; } };
- コードサンプル7-16 サーバントアクティベータのサンプルのサーバントマネージャ(Java)
import org.omg.PortableServer.*; public class AccountManagerActivator extends ServantActivatorPOA { public Servant incarnate ( byte[ ] oid, POA adapter) throws ForwardRequest { Servant servant; String accountType = new String(oid); System.out.println( "\nAccountManagerActivator.incarnate called with ID = " + accountType + "\n"); // Create Savings or Checking Servant based on // AccountType if ( accountType.equalsIgnoreCase( "SavingsAccountManager")) servant = (Servant )new SavingsAccountManagerImpl(); else servant = (Servant)new CheckingAccountManagerImpl(); new DeactivateThread(oid, adapter).start(); return servant; } public void etherealize (byte[ ] oid, POA adapter, Servant serv, boolean cleanup_in_progress, boolean remaining_activations){ System.out.println( "\nAccountManagerActivator. etherealize called with ID = " + new String(oid) + "\n"); System.gc(); } } class DeactivateThread extends Thread { byte[ ] _oid; POA _adapter; public DeactivateThread(byte[ ] oid, POA adapter) { _oid = oid; _adapter = adapter; } public void run(){ try { Thread.currentThread().sleep(15000); System.out.println( "\nDeactivating the object with ID = " + new String(_oid) + "\n"); _adapter.deactivate_object(_oid); }catch (Exception e) { e.printStackTrace(); } } }