7.5.1 ServantActivator

C++の場合
ServantActivatorは,ServantRetentionPolicy::RETAINとRequestProcessingPolicy::USE_SERVANT_MANAGERが設定された場合に使用します。
Javaの場合
ServantActivatorは,ServantRetentionPolicy.RETAINとRequestProcessingPolicy.USE_SERVANT_MANAGERが設定された場合に使用します。

このタイプのサーバントマネージャによって活性化されたサーバントは,アクティブオブジェクトマップで管理されます。

サーバントアクティベータを使用したリクエストの処理中には,次のようなイベントが発生します。

  1. クライアントリクエストを受信します(クライアントリクエストにはPOA名,オブジェクトIDなどの情報が含まれます)。
  2. POAはまず,アクティブオブジェクトマップをチェックします。オブジェクトIDがそこで見つかれば,オペレーションはサーバントに渡され,クライアントに応答が返されます。
  3. アクティブオブジェクトマップにオブジェクトIDが見つからなければ,POAはサーバントマネージャのincarnateを呼び出します。incarnateはオブジェクトIDと,オブジェクトを活性化しているPOAを渡します。
  4. サーバントマネージャは適切なサーバントを探します。
  5. サーバント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();
    }
  }
}