Horus Doc || Corba Reference || Corba   Client Server   Stubs C++   Stubs Java   Servant Generator  

Portable object adapter (POA)

The standard object adapter defined in the Corba specification is the Portable Object Adapter (POA). It provides features necessary to allow programming language servants to be portable among ORBs supplied by different vendors. A server application may contain multiple POA instances to support Corba objects with different characteristics or to support multiple servant implementation styles.

IncomingRequest.gif

Incoming request

Conceptually, requests for Corba objects residing in the server application are sent from a client and arrive at the server ORB, which dispatches them to the POA in which the target object was created (dispatch is based on the object key). The POA then further dispatches the request to the servant incarnating the target object (using the object identifier).

A server cannot accept any incoming requests until it tells its ORB to start listening for them. In addition, because a single server application may contain multiple POAs, the flow of requests into each POA is controlled by a POAManager object associated with that POA. In addition to letting requests flow into a POA, a POAManager can queue requests for later dispatch or can discard them.

PoaManager.gif

POA manager

In a server application, a POA is responsible for creating object references, activating objects, and dispatching requests made on objects to their respective servants. As such, the POA deals with three key entities : object references, object identifiers (a sequence of octets), and servants. How a POA handles these entities is determined via policies that are specified when a POA is created. All server applications have at least one POA, the Root POA, which has a standard set of policies.

LifespanPolicy
(TRANSIENT, PERSISTENT) Controls the object life span. The default is TRANSIENT. The Root POA uses the default.
IdAssignmentPolicy
(USER_ID, SYSTEM_ID) Controls object identification, i.e. generation of object identifiers. Typically, an application that uses persistent objects supplies its own identifiers (USER_ID) because it uses them to keep track of where it stores the persistent state of the object. Applications that use transient objects usually let the POA create identifiers for them (SYSTEM_ID). The default is SYSTEM_ID. The Root POA uses the default.
IdUniquenessPolicy
(UNIQUE_ID, MULTIPLE_ID) Allows a single servant to incarnate multiple Corba objects, or restricts servants to incarnating only a single object. Basically, the policy controls the entries in the Active Object Map of the POA. Each entry consists of an association between an ObjectId and a pointer to a servant. With UNIQUE_ID, each ObjectId must map to a different servant. With MULTIPLE_ID, multiple ObjectId's can map to a single servant. The default is UNIQUE_ID. The Root POA uses the default.
ImplicitActivationPolicy
(IMPLICIT_ACTIVATION, NO_IMPLICIT_ACTIVATION) Specifies that the POA should allow Corba objects to be created and activated implicitly or that only explicit Corba object creation and servant registration is allowed. Implicit activation is usually performed through a shortcut function supplied by a language mapping, such as the _this function provided by C++ skeleton classes. The default is NO_IMPLICIT_ACTIVATION. The Root POA uses IMPLICIT_ACTIVATION.
RequestProcessingPolicyValue
(USE_ACTIVE_OBJECT_MAP_ONLY, USE_DEFAULT_SERVANT, USE_SERVANT_MANAGER) Controls associations between objects and servants. An application containing many thousands of objects may want to incarnate only those objects that actually receive requests. It does this by registering a servant manager with the POA. Servant managers are local objects that are up-called by a POA if it receives an invocation on an object that has no associated servant. Depending upon the POA's value for the IdUniquenessPolicy, the servant manager can either provide the POA with a newly created servant or reuse an existing one. Either way, it returns the servant as the result of the up-call, which the POA uses to complete the request invocation. After the invocation completes, the POA either retains the association of the servant and the Corba object in its Active Object Map or throws the association away, meaning that the next invocation on the object will again require the services of the servant manager. Still anoher alternative is for applications to supply a default servant to a POA. A default servant incarnates all Corba objects for a POA. The default is USE_ACTIVE_OBJECT_MAP_ONLY. The Root POA uses the default.
ServantRetentionPolicy
(RETAIN, NON_RETAIN) Specifies whether associations between objects and servants should be retained in the Active Object Map. The default is RETAIN. The Root POA uses the default.
ThreadPolicy
(ORB_CTRL_MODEL, SINGLE_THREAD_MODEL) Specifies the threading model used for handling requests. The ORB-controlled model allows the underlying ORB implementation to choose an appropriate multithreading model, whereas the single-thread model guarantees that all requests for all objects in that POA will be dispatched sequentially. The default is ORB_CTRL_MODEL. The Root POA uses the default.

A POA is created by invoking the create_POA operation on another POA. Because all server applications have a Root POA, its create_POA operation serves as the starting point for creating other POAs. The Root POA is obtained via ServantBase::_default_POA. A POA created using another POA becomes a child POA of the creating POA. Note, however, that this has no effect on the policies of the child POA. Policies are not inherited. During shutdown, child POAs are destroyed before their parents, meaning that the Root POA is the last POA to be destroyed.

The POA provides several options for creating objects and activating them by servant registration:

Object creation without creating any servants
The POA interface provides two functions for this : create_reference and create_reference_with_id. Both create a Corba object (without creating a servant) using a RepositoryId that identifies the most derived IDL interface that the new object will support.
Servant registration
The POA interface provides two functions for this : activate_object and activate_object_with_id. With these operations, the user explicitly supplies a servant to incarnate the object being activated.
Servant managers
There are two types of servant managers, i.e. interfaces to be implemented by the user supplied servant manager object (both interfaces are derived from the ServantManager interface):
ServantActivator (ServantRetentionPolicy == RETAIN)
The interface supplies the incarnate and etherealize operations. When the POA receives a request for a target object that is not in its Active Object Map, it calls the incarnate function of the servant manager to supply the servant. The POA normally invokes the etherealize operation in response to an explicit object deactivation via deactivate_object (even if the servant for that object was not created by the servant activator) or in response to the deactication or destruction of the POA itself.
ServantLocator (ServantRetentionPolicy == NON_RETAIN)
The interface supplies the preinvoke and postinvoke operations. The POA does not store object-to-servant associations in its Active Object Map, so it must invoke its ServantLocator for each incoming request. If first invokes preinvoke to obtain a servant to dispatch the request to. After the request returns, the POA invokes postinvoke.
Because servant managers are themselves Corba objects, they must be created and activated before they can be registered with a POA. The easiest way to create an object reference for a servant manager is to implicitly register its servant in the Root POA using _this(). The registration as a servant manager is done via the set_servant_manager function of the POA.
Default servants
The POA interface provides the set_servant function for this. The default servant acts as a catch-all servant for those objects that do not have their own servants. Each object incarnated by the default servant must support the same interface. Because they incarnate multiple Corba objects, a key aspect is that a default servant must not hold object-specific state, so that must be contained within the ObjectId. Wihtin the context of a request dispatch, the server ORB allows to obtain the ObjectId of the target object and a reference to the POA that is dispatching the request via the PortableServer::Current interface. You obtain a reference to the POA Current by passing the string "POACurrrent" to ORB::resolve_initial_references.

Memory related problems with servants are best avoided by deriving the servant class from the RefCountServantBase class provided in the PortableServer namespace. The interface provides the _add_ref and _remove_ref functions. Unlike the do-nothing versions of the _add_ref and _remove_ref functions supplied by PortableServer::ServantBase, the versions provided by the RefCountServantBase class perform thread-safe reference counting for derived servant classes.

Like servants, POAs can be created on demand. POA activation occurs when a request arrives for an object in a descendant POA that has not yet been created or when the application searches a hierarchy of POAs using the POA::find_POA operation for a named POA that has not yet been created. The application registers an AdapterActivator with each POA that must activate its descendant POAs. Adapter activators are normal Corba objects, so they are incarnated via servants.


Go to the next section or return to the index.


Generated on Mon Jan 27 15:20:57 2003 for CorbaReference by doxygen1.2.12 written by Dimitri van Heesch, © 1997-2001