Borland(R) Enterprise Server VisiBroker(R) デベロッパーズガイド
POAのアクティブオブジェクトマップがきわめて大きくなりメモリを消費するような状況はよくあります。メモリ消費量を減らすために,サーバントとオブジェクトの対応をアクティブオブジェクトマップに格納しないという意味のRequestProcessingPolicy::USE_SERVANT_MANAGERとServantRetentionPolicy::NON_RETAIN(C++)設定,またはRequestProcessingPolicy.USE_SERVANT_MANAGERとServantRetentionPolicy.NON_RETAIN(Java)設定でPOAを作成できます。対応が格納されないので,ServantLocatorサーバントマネージャをリクエストごとに起動できます。
サーバントロケータを使用したリクエストの処理中には,次のようなイベントが発生します。
int main(int argc, char* const* argv) { try { // Initialize the ORB. CORBA::ORB_ptr orb = CORBA::ORB_init(argc, argv); // And the Data source 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(3); // Create a child POA with Persistence life span policy // that uses servant manager with non-retain retention // policy ( no Active Object Map ) causing the POA to use // the servant locator. policies[(CORBA::ULong)0] = rootPOA->create_lifespan_policy (PortableServer::PERSISTENT); policies[(CORBA::ULong)1] = rootPOA->create_servant_retention_policy (PortableServer::NON_RETAIN); policies[(CORBA::ULong)2] = rootPOA->create_request_processing_policy (PortableServer::USE_SERVANT_MANAGER); PortableServer::POAManager_var rootManager = rootPOA->the_POAManager(); PortableServer::POA_var myPOA = rootPOA->create_POA("bank_servant_locator_poa", rootManager, policies); // Create the servant locator AccountManagerLocator servant_locator_impl; myPOA->set_servant_manager(&servant_locator_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(); // Wait for incoming requests cout << "Bank Manager is ready" << endl; orb->run(); // Destroy the accounts database DataStore::_destroy(); } catch(const CORBA::Exception& e) { cerr << e << endl; } return 1; }
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.ORB.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, // use servant manager request processing // policies and non retain retention policy. // This non retain policy will let us use the // servant locator instead of servant activator org.omg.CORBA.Policy[ ] policies = { rootPOA.create_lifespan_policy( LifespanPolicyValue.PERSISTENT), rootPOA.create_servant_retention_policy( ServantRetentionPolicyValue.NON_RETAIN), rootPOA.create_request_processing_policy( RequestProcessingPolicyValue. USE_SERVANT_MANAGER) }; // Create myPOA with the right policies POA myPOA = rootPOA.create_POA( "bank_servant_locator_poa", rootPOA.the_POAManager(), policies ); // Create the servant locator servant // and get its reference ServantLocator sl = new AccountManagerLocator()._this(orb); // Set the servant locator on our POA myPOA.set_servant_manager(sl); 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("BankManager is ready."); // Wait for incoming requests orb.run(); } catch (Exception e) { e.printStackTrace(); } } }
このサンプルのサーバントマネージャは,次のとおりです。
// Servant Locator class AccountManagerLocator : public PortableServer::ServantLocator { public: AccountManagerLocator (){} // preinvoke is very similar to ServantActivator 's // incarnate method but gets called every time a // request comes in unlike incarnate() which gets called // every time the POA does not find a servant in the // active object map virtual PortableServer::Servant preinvoke (const PortableServer::ObjectId& oid, PortableServer::POA_ptr adapter, const char* operation, PortableServer::ServantLocator:: Cookie& the_cookie) { CORBA::String_var s = PortableServer::ObjectId_to_string (oid); cout << "\nAccountManagerLocator.preinvoke 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(); // Note also that we do not spawn of a thread to // explicitly deactivate an object unlike a servant // activator , this is because the POA itself calls // post invoke after the request is complete.In the // case of a servant activator the POA calls // etherealize() only if the object is deactivated // by calling poa->de_activate object or the POA // itself is destroyed. //return the servant return servant; } virtual void postinvoke (const PortableServer::ObjectId& oid, PortableServer::POA_ptr adapter, const char* operation, PortableServer::ServantLocator::Cookie the_cookie, PortableServer::Servant the_servant) { CORBA::String_var s = PortableServer::ObjectId_to_string (oid); cout << "\nAccountManagerLocator.postinvoke called with ID = " << s << endl; delete the_servant; } };
import org.omg.PortableServer.*; import org.omg.PortableServer. ServantLocatorPackage.CookieHolder; public class AccountManagerLocator extends ServantLocatorPOA { public Servant preinvoke (byte[ ] oid,POA adapter, java.lang.String operation, CookieHolder the_cookie) throws ForwardRequest { String accountType = new String(oid); System.out.println( "\nAccountManagerLocator. preinvoke called with ID = " + accountType + "\n"); if ( accountType.equalsIgnoreCase ("SavingsAccountManager")) return new SavingsAccountManagerImpl(); return new CheckingAccountManagerImpl(); } public void postinvoke (byte[ ] oid, POA adapter, java.lang.String operation, java.lang.Object the_cookie, Servant the_servant) { System.out.println( "\nAccountManagerLocator.postinvoke called with ID = " + new String(oid) + "\n"); } }
All Rights Reserved. Copyright (C) 2006, Hitachi, Ltd.
COPYRIGHT (C) 1992-2004 Borland Software Corporation. All rights reserved.