diff options
Diffstat (limited to 'TAO/docs/tutorials/Quoter/On_Demand_Activation/index.html')
-rw-r--r-- | TAO/docs/tutorials/Quoter/On_Demand_Activation/index.html | 280 |
1 files changed, 280 insertions, 0 deletions
diff --git a/TAO/docs/tutorials/Quoter/On_Demand_Activation/index.html b/TAO/docs/tutorials/Quoter/On_Demand_Activation/index.html new file mode 100644 index 00000000000..63e4fa14445 --- /dev/null +++ b/TAO/docs/tutorials/Quoter/On_Demand_Activation/index.html @@ -0,0 +1,280 @@ + +<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> +<html> + <head> + <title>Servant Managers</title> + <!-- $Id$ --> + </head> + + <body text = "#000000" + link="#000fff" + vlink="#ff0f0f" + bgcolor="#ffffff"> + + <h1>Servant Managers</h1> + <P>In our <a href=../AMI/index.html>previous example</a>, we + extended our <a href=../Simple/Client/client.cpp>simple client</a> + using synchronous method invocation to handle asynchronous + requests: Asynchronous Method Invocation by using + the reply handlers. + </P> + <P>In applications which have many objects, activating + all of them all the time would be unnecessary + and also might require too much memory or too many database + lookups. For such applications, the POA provides an option + for the application to supply servant managers that can + dynamically supply servants on a per-request basis. + </P> + <p> A servant manager is a call-back object that the application + registers with a POA. When the POA attempts to determine the + servant associated with a particular request, it calls back the + application's servant manager to obtain the servant. To be able + to register a servant manager with the POA, the + <CODE>RequestProcessingPolicyValue</CODE>, which controls the + matching of requests to servants, is to be set to + <CODE>USE_SERVANT_MANAGER</CODE>. + </P> + <P>There are two types of servant managers depending on whether the POA + retains the associations of objects to servants in its Active + Object Map or not. This is determined by the value of the + <CODE>ServantRetentionPolicy</CODE> set when the + POA is created. If the value of this policy is set as RETAIN, + the POA retains the associations, and if the policy value is set + to be NON_RETAIN, the POA doesn't retain any associations between + the object and the servant. + </P> + <P>For a POA with the RETAIN value, the servant manager must + activate the servant associated with the object. This would need + the servant manager object to support the ServantActivator + interface. In the case of a POA with the NON_RETAIN value set, + our servant manager object should be able to locate the servant + for the requested object and then invoke it. + </P> + <P>In this example, let's use a servant locator to locate the + servant associated with our Stock_Factory object when a request + is invoked on this object. + </P> + <H3>The Stock Factory Locator Implementation</H3> + <P>Our implementation of the Stock_Factory_Locator_i will help + us find the Quoter_Stock_Factory servant. + </P> + <P>A servant Locator interface provides two operations: preinvoke + and postinvoke. The preinvoke operation is invoked to obtain the + servant to dispatch the request to. The servant returned by + the preinvoke is used only for a single request. The postinvoke + operation is later invoked to destroy the servant created by the + preinvoke operation. + </P> + <PRE> + #include "tao/corba.h" + + class Quoter_Stock_Factory_Locator_i : public POA_PortableServer::ServantLocator + { + public: + Quoter_Stock_Factory_Locator_i (CORBA::ORB_ptr orb); + + // Preinvoke function + virtual PortableServer::Servant preinvoke (const PortableServer::ObjectId &oid, + PortableServer::POA_ptr poa, + const char * operation, + void * & cookie) + throw (CORBA::SystemException, PortableServer::ForwardRequest); + + // Postinvoke function + virtual void postinvoke (const PortableServer::ObjectId & oid, + PortableServer::POA_ptr poa, + const char * operation, + void * cookie, + PortableServer::Servant servant) + throw (CORBA::SystemException); + + private: + CORBA::ORB_var orb_; + }; + </PRE> + <P>In the implementation of the <CODE>preinvoke</CODE> operation, we check if + the object ID is valid and then check for the servant we want to + create and create and return the requested servant. + <PRE> + <PRE> + PortableServer::Servant + Quoter_Stock_Factory_Locator_i::preinvoke (const PortableServer::ObjectId &oid, + PortableServer::POA_ptr poa, + const char * operation, + void * & cookie) + throw (CORBA::SystemException, PortableServer::ForwardRequest) + { + + try { + + // Get the ObjectID in string format + CORBA::String_var oid_str = + PortableServer::ObjectId_to_string (oid); + + // Check if the ObjectId is valid + if (strcmp (oid_str.in (), "Quoter/Stock_Factory") != 0) { + // Create the requested servant. + PortableServer::Servant servant = + new Quoter_Stock_Factory_i (); + + cookie = servant; + + return servant; + } + else { + throw CORBA::OBJECT_NOT_EXIST (); + } + + }catch (const CORBA::BAD_PARAM &) { + throw CORBA::OBJECT_NOT_EXIST (); + } + </PRE> + <P>The implementation of the <CODE>postinvoke</CODE> operation is + simple. We just destroy the servant which we created by the + <CODE>preinvoke</CODE> operation. The <CODE>Cookie IDL + type</CODE> which is a parameter in both these operations + helps associate the invocation of <CODE>preinvoke</CODE> with + its <CODE>postinvoke</CODE> operation. + </P> + <PRE> + void + Quoter_Stock_Factory_Locator_i::postinvoke (const PortableServer::ObjectId &oid, + PortableServer::POA_ptr poa, + const char * operation, + void * cookie, + PortableServer::Servant servant) + throw (CORBA::SystemException) + { + + // Delete the servant as it is no longer needed. + PortableServer::Servant my_servant = (PortableServer::Servant) cookie; + if (servant == my_servant) + delete servant; + } + </PRE> + <H3> Server Implementation </H3> + <P>Our first steps would be to create a new POA from the RootPOA + with the <CODE>USE_SERVANT_MANAGER</CODE> value for the + <CODE>RequestProcessingPolicy</CODE> and <CODE>NON_RETAIN</CODE> + for the <CODE>ServantRetentionPolicy</CODE>. + </P> + <PRE> + CORBA::PolicyList policies (3); + policies.length (3); + + // Assign the polices + policies [0] = + poa->create_id_assignment_policy (PortableServer::USER_ID); + + policies [1] = + poa->create_request_processing_policy + (PortableServer::USE_SERVANT_MANAGER); + + policies [2] = + poa->create_servant_retention_policy (PortableServer::NON_RETAIN); + + // Create the POA with these policies + PortableServer::POA_var child_poa = + poa->create_POA ("childPOA", + poa_manager.in (), + policies); + + // Destroy the policy objects + for (CORBA::ULong i = 0; i != policies.length (); ++i) { + policies[i]->destroy (); + } + + </PRE> + <P> The policy values are assigned, the <CODE>childPOA</CODE> is + created with these policies, and later these policy objects can be + deleted, as a copy of these objects is made by the + <CODE>create_POA</CODE> and we would not need these objects any more. + </P> + <P> Now that we have the POA which can support servant managers, + the next step would be to create a servant for the servant + locator object, activate it to obtain its reference, and set it as + the servant manager with the childPOA. + </P> + <PRE> + // Create a Stock_Factory_Locator servant + Quoter_Stock_Factory_Locator_i servant_locator_i(orb.in ()); + + // Need to activate a servant_manager object in the Root POA + PortableServer::ServantLocator_var servant_locator = + servant_locator_i._this (); + + // Set the SM with the childPOA + child_poa->set_servant_manager (servant_locator.in ()); + </PRE> + <P>Now that we have set the servant manager with the childPOA, the + next step would be to create a reference with the user-created + ID in the childPOA which uses the Quoter_Stock_Factory_Locator_i. + The <CODE>create_reference_with_id</CODE> operation lets us + create the required object without actually creating its servant. + The application supplies the ObjectId which signifies the + identity of the object in the application domain. + </P> + <PRE> + // Get the Object Id + PortableServer::ObjectId_var child_oid = + PortableServer::string_to_ObjectId ("childFoo"); + + //Create the Object without creating the servants + CORBA::Object_var stock_factory = + child_poa->create_reference_with_id (child_oid.in (), + "IDL:Quoter/Stock_Factory:1.0"); + </PRE> + <P>After this, as before, let's put this object reference as an IOR + string and print it out. + </P> + <PRE> + // Put the object reference as an IOR string + CORBA::String_var ior = orb->object_to_string (stock_factory.in ()); + + // Print it out! + std::cout << ior.in () << std::endl; + </PRE> + <H3>Excercise</H3> + <P>Modify the <a href="../Simple/Server/server.cpp">server.cpp</a> in + the simple server to use servant managers and locators. Use + these files to help complete the implementation. + <a href="Stock_Factory_Locator_i.h">Stock_Factory_locator_i.h</a> + <a href="Stock_Factory_Locator_i.cpp">Stock_Factory_locator_i.cpp</a> + <a href="Makefile">Makefile</a>. + </P> + <H3>Solution</H3> + <P>Look at the <a href="server.cpp">server.cpp</a> file. It should not + be much different from yours. + </P> + <H3>Testing</H3> + <P>A client which uses request handlers is provided: + <a href="../AMI/client.cpp">client.cpp</a>. As before the + following files are provided. + <a href="../AMI/Quoter.idl">Quoter.idl</a> + <a href="../On_Demand_Activation/Stock_i.h">Stock_i.h</a> + <a href="../On_Demand_Activation/Stock_i.cpp">Stock_i.cpp</a> + <a href="Stock_Factory_i.h">Stock_Factory_i.h</a> + <a href="Stock_Factory_i.cpp">Stock_Factory_i.cpp</a> + <a href="../AMI/Handler_i.h">Handler_i.h</a> and + <a href="../AMI/Handler_i.cpp">Handler_i.cpp</a>. + </P> + <H3>More Reading</H3> + <P>The + <P>The <A HREF="http://www.triodia.com/staff/michi-henning.html">Henning</A> and + <A HREF="http://www.iona.com/hyplan/vinoski/">Vinoski</A> + <A HREF="http://www.iona.com/hyplan/vinoski/#book">CORBA book</A> + discusses POA policies in detail. Likewise, the Schmidt and Vinoski + <A HREF="http://www.cs.wustl.edu/~schmidt/report-doc.html">columns </A> + in C++ Report also include several articles about the POA. Finally, + the <A HREF="http://www.cs.wustl.edu/~schmidt/TAO.html">TAO</a> + distribution includes + <A HREF="../../../../examples/POA">examples</A> that illustrate how to use the POA policies. + </P> + <hr> + <address><a href="mailto:pgontla@ece.uci.edu">Priyanka Gontla</a></address> + <!-- Created: Mon May 1 11:08:56 PDT 2000 --> + <!-- hhmts start --> +Last modified: Tue Apr 24 17:50:17 CDT 2001 +<!-- hhmts end --> + </body> +</html> |