Borland(R) Enterprise Server VisiBroker(R) デベロッパーズガイド

[目次][索引][前へ][次へ]

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();
     }
   }
}