summaryrefslogtreecommitdiff
path: root/TAO/docs/tutorials/Quoter/On_Demand_Activation/index.html
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/docs/tutorials/Quoter/On_Demand_Activation/index.html')
-rw-r--r--TAO/docs/tutorials/Quoter/On_Demand_Activation/index.html280
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>