Note: This section contains excerpts from the POA specification.This chapter describes the Portable Object Adapter, or POA. It presents the design goals, a description of the abstract model of the POA and its interfaces, followed by a detailed description of the interfaces themselves.
The POA is designed to meet the following goals:
- Allow programmers to construct object implementations that are portable between different ORB products.
- Provide support for objects with persistent identities. More precisely, the POA is designed to allow programmers to build object implementations that can provide consistent service for objects whose lifetimes (from the perspective of a client holding a reference for such an object) span multiple server lifetimes.
- Provide support for transparent activation of objects.
- Allow a single servant to support multiple object identities simultaneously.
- Allow multiple distinct instances of the POA to exist in a server.
- Provide support for transient objects with minimal programming effort and overhead.
- Provide support for implicit activation of servants with POA-allocated Object Ids.
- Allow object implementations to be maximally responsible for an object's behavior. Specifically, an implementation can control an object's behavior by establishing the datum that defines an object's identity, determining the relationship between the object's identity and the object's state, managing the storage and retrieval of the object's state, providing the code that will be executed in response to requests, and determining whether or not the object exists at any point in time.
- Avoid requiring the ORB to maintain persistent state describing individual objects, their identities, where their state is stored, whether certain identity values have been previously used or not, whether an object has ceased to exist or not, and so on.
- Provide an extensible mechanism for associating policy information with objects implemented in the POA.
- Allow programmers to construct object implementations that inherit from static skeleton classes, generated by OMG IDL compilers, or a DSI implementation.
Abstract Model Description
The POA interfaces described in this chapter imply a particular abstract computational model. This section presents that model and defines terminology and basic concepts that will be used in subsequent sections.This section provides the rationale for the POA design, describes some of its intended uses, and provides a background for understanding the interface descriptions.
Model Components
The abstract model supported by the POA has the following components:
- Client A client is a computational context that makes requests on an object through one of its references.
- Server A server is a computational context in which the implementation of an object exists. Generally, a server corresponds to a process. Note that client and server are roles that programs play with respect to a given object. A program that is a client for one object may be the server for another. The same process may be both client and server for a single object.
- Object In this discussion, we use object to indicate a CORBA object in the abstract sense, that is, a programming entity with an identity, an interface, and an implementation. From a client's perspective, the object's identity is encapsulated in the object's reference. This specification defines the server's view of object identity, which is explicitly managed by object implementations through the POA interface.
- Servant A servant is a programming language object or entity that implements requests on one or more objects. Servants generally exist within the context of a server process. Requests made on an object's references are mediated by the ORB and transformed into invocations on a particular servant. In the course of an object's lifetime it may be associated with (that is, requests on its references will be targeted at) multiple servants.
- Object Id An Object Id is a value that is used by the POA and by the user-supplied implementation to identify a particular abstract CORBA object. Object Id values may be assigned and managed by the POA, or they may be assigned and managed by the implementation. Object Id values are hidden from clients, encapsulated by references. Object Ids have no standard form; they are managed by the POA as uninterpreted octet sequences.
- Object Reference An object reference in this model is the same as in the CORBA object model. This model implies, however, that a reference specifically encapsulates an Object Id and a POA identity.
- POA A POA is an identifiable entity within the context of a server. Each POA provides a namespace for Object Ids and a namespace for other (nested or child) POAs. Policies associated with a POA describe characteristics of the objects implemented in that POA. Nested POAs form a hierarchical name space for objects within a server.
- Policy A Policy is an object associated with a POA by an application in order to specify a characteristic shared by the objects implemented in that POA. This specification defines policies controlling the POA's threading model as well as a variety of other options related to the management of objects. Other specifications may define other policies that affect how an ORB processes requests on objects implemented in the POA.
- POA Manager A POA manager is an object that encapsulates the processing state of one or more POAs. Using operations on a POA manager, the developer can cause requests for the associated POAs to be queued or discarded. The developer can also use the POA manager to deactivate the POAs.
- Servant Manager A servant manager is an object that the application developer can associate with a POA. The ORB will invoke operations on servant managers to activate servants on demand, and to deactivate servants. Servant managers are responsible for managing the association of an object (as characterized by its Object Id value) with a particular servant, and for determining whether an object exists or not. There are two kinds of servant managers, called ServantActivator and ServantLocator; the type used in a particular situation depends on policies in the POA.
- Adapter Activator An adapter activator is an object that the application developer can associate with a POA. The ORB will invoke an operation on an adapter activator when a request is received for a child POA that does not currently exist. The adapter activator can then create the required POA on demand.
Model Architecture
This section describes the architecture of the abstract model implied by the POA, and the interactions between various components. The ORB is an abstraction visible to both the client and server. The POA is an object visible to the server. User-supplied implementations are registered with the POA (this statement is a simplification; more detail is provided below). Clients hold references upon which they can make requests. The ORB, POA, and implementation all cooperate to determine which servant the operation should be invoked on, and to perform the invocation.Fig 1: Abstract POA Model. The figure above shows the detail of the relationship between the POA and the implementation. Ultimately, a POA deals with an Object Id and an active servant. By active servant, we mean a programming object that exists in memory and has been presented to the POA with one or more associated object identities. There are several ways for this association to be made.
If the POA supports the RETAIN policy, it maintains a map, labeled Active Object Map, that associates Object Ids with active servants, each association constituting an active object. If the POA has the USE_DEFAULT_SERVANT policy, a default servant may be registered with the POA. Alternatively, if the POA has the USE_SERVANT_MANAGER policy, a user-written servant manager may be registered with the POA. If the Active Object Map is not used, or a request arrives for an object not present in the Active Object Map, the POA either uses the default servant to perform the request or it invokes the servant manager to obtain a servant to perform the request. If the RETAIN policy is used, the servant returned by a servant manager is retained in the Active Object Map. Otherwise, the servant is used only to process the one request.
An object is active in a POA if the POA's Active Object Map contains an entry that associates an Object Id with an existing servant.
Fig 2: POA Architecture. POA Creation
To implement an object using the POA requires that the server application obtain a POA object. A distinguished POA object, called the Root POA, is managed by the ORB and provided to the application using the ORB initialization interface under the initial object name "RootPOA." The application developer can create objects using the root POA if those default policies are suitable. The root POA has the following policies.The developer can also create new POAs. Creating a new POA allows the application developer to declare specific policy choices for the new POA and to provide a different adapter activator and servant manager (these are callback objects used by the POA to activate objects and nested POAs on demand). Creating new POAs also allows the application developer to partition the name space of objects, as Object Ids are interpreted relative to a POA. Finally, by creating new POAs, the developer can independently control request processing for multiple sets of objects.
- Thread Policy: ORB_CTRL_MODEL
- Lifespan Policy: TRANSIENT
- Object Id Uniqueness Policy: UNIQUE_ID
- Id Assignment Policy: SYSTEM_ID
- Servant Retention Policy: RETAIN
- Request Processing Policy: USE_ACTIVE_OBJECT_MAP_ONLY
- Implicit Activation Policy: IMPLICIT_ACTIVATION
A POA is created as a child of an existing POA using the create_POA operation on the parent POA. When a POA is created, the POA is given a name that must be unique with respect to all other POAs with the same parent.
POA objects are not persistent. No POA state can be assumed to be saved by the ORB. It is the responsibility of the server application to create and initialize the appropriate POA objects during server initialization or to set an AdapterActivater to create POA objects needed later.
Creating the appropriate POA objects is particularly important for persistent objects, objects whose existence can span multiple server lifetimes. To support an object reference created in a previous server process, the application must recreate the POA that created the object reference as well as all of its ancestor POAs. To ensure portability, each POA must be created with the same name as the corresponding POA in the original server process and with the same policies. (It is the user's responsibility to create the POA with these conditions.)
A portable server application can presume that there is no conflict between its POA names and the POA names chosen by other applications. It is the responsibility of the ORB implementation to provide a way to support this behavior.
Reference Creation
Object references are created in servers. Once they are created, they may be exported to clients.From this model's perspective, object references encapsulate object identity information and information required by the ORB to identify and locate the server and POA with which the object is associated (that is, in whose scope the reference was created.) References are created in the following ways:
Once a reference is created in the server, it can be made available to clients in a variety of ways. It can be advertised through the OMG Naming and Trading Services. It can be converted to a string via ORB::object_to_string and published in some way that allows the client to discover the string and convert it to a reference using ORB::string_to_object. It can be returned as the result of an operation invocation.
- The server application may directly create a reference with the create_reference and create_reference_with_id operations on a POA object. These operations collect the necessary information to constitute the reference, either from information associated with the POA or as parameters to the operation. These operations only create a reference. In doing so, they bring the abstract object into existence, but do not associate it with an active servant.
- The server application may explicitly activate a servant, associating it with an object identity using the activate_object or activate_object_with_id operations. Once a servant is activated, the server application can map the servant to its corresponding reference using the servant_to_reference or id_to_reference operations.
- The server application may cause a servant to implicitly activate itself. This behavior can only occur if the POA has been created with the IMPLICIT_ACTIVATION policy. If an attempt is made to obtain an object reference corresponding to an inactive servant, the POA may automatically assign a generated unique Object Id to the servant and activate the resulting object. The reference may be obtained by invoking servant_to_reference with an inactive servant, or by performing an explicit or implicit type conversion from the servant to a reference type in programming language mappings that permit this conversion.
Once a reference becomes available to a client, that reference constitutes the identity of the object from the client's perspective. As long as the client program holds and uses that reference, requests made on the reference should be sent to the "same" object.
The states of servers and implementation objects are opaque to clients. The POA deals primarily with the view of the ORB from the server's perspective.
Object Activation States
At any point in time, a CORBA object may or may not be associated with an active servant.If the POA has the RETAIN policy, the servant and its associated Object Id are entered into the Active Object Map of the appropriate POA. This type of activation can be accomplished in one of the following ways.
If the USE_DEFAULT_SERVANT policy is also in effect, the server application instructs the POA to activate unknown objects by having the POA invoke a single servant no matter what the Object Id is. The server application registers this servant with set_servant.
- The server application itself explicitly activates individual objects (via the activate_objector activate_object_with_id operations).
- The server application instructs the POA to activate objects on demand by having the POA invoke a user-supplied servant manager. The server application registers this servant manager with set_servant_manager.
- Under some circumstances (when the IMPLICIT_ACTIVATION policy is also in effect and the language binding allows such an operation), the POA may implicitly activate an object when the server application attempts to obtain a reference for a servant that is not already active (that is, not associated with an Object Id).
If the POA has the NON_RETAIN policy, for every request, the POA may use either a default servant or a servant manager to locate an active servant. From the POA's point of view, the servant is active only for the duration of that one request. The POA does not enter the servant-object association into the Active Object Map.
Request Processing
A request must be capable of conveying the Object Id of the target object as well as the identification of the POA that created the target object reference. When a client issues a request, the ORB first locates an appropriate server (perhaps starting one if needed) and then it locates the appropriate POA within that server.If the POA does not exist in the server process, the application has the opportunity to re-create the required POA by using an adapter activator. An adapter activator is a user-implemented object that can be associated with a POA. It is invoked by the ORB when a request is received for a non-existent child POA. The adapter activator has the opportunity to create the required POA. If it does not, the client receives the OBJECT_NOT_EXIST exception.
Once the ORB has located the appropriate POA, it delivers the request to that POA. The further processing of that request depends both upon the policies associated with that POA as well as the object's current state of activation.
If the POA has the RETAIN policy, the POA looks in the Active Object Map to find if there is a servant associated with the Object Id value from the request. If such a servant exists, the POA invokes the appropriate method on the servant.
If the POA has the NON_RETAIN policy or has the RETAIN policy but didn't find a servant in the Active Object Map, the POA takes the following actions:
If a servant manager is located and invoked, but the servant manager is not directly capable of incarnating the object, it (the servant manager) may deal with the circumstance in a variety of ways, all of which are the application's responsibility. Any system exception raised by the servant manager will be returned to the client in the reply. In addition to standard CORBA exceptions, a servant manager is capable of raising a ForwardRequest exception. This exception includes an object reference. The ORB will process this exception as stated below.
- If the POA has the USE_DEFAULT_SERVANT policy, a default servant has been associated with the POA so the POA will invoke the appropriate method on that servant. If no servant has been associated with the POA, the POA raises the OBJ_ADAPTER system exception.
- If the POA has the USE_SERVANT_MANAGER policy, a servant manager has been associated with the POA so the POA will invoke incarnate or preinvoke on it to find a servant that may handle the request. (The choice of method depends on the NON_RETAIN or RETAIN policy of the POA.) If no servant manager has been associated with the POA, the POA raises the OBJ_ADAPTER system exception.
- If the USE_OBJECT_MAP_ONLY policy is in effect, the POA raises the OBJECT_NOT_EXIST system exception.
Implicit Activation
A POA can be created with a policy that indicates that its objects may be implicitly activated. This policy, IMPLICIT_ACTIVATION, also requires the SYSTEM_ID and RETAIN policies. When a POA supports implicit activation, an inactive servant may be implicitly activated in that POA by certain operations that logically require an Object Id to be assigned to that servant. Implicit activation of an object involves allocating a system-generated Object Id and registering the servant with that Object Id in the Active Object Map. The interface associated with the implicitly activated object is determined from the servant.The operations that support implicit activation include:
If the POA has the UNIQUE_ID policy, then implicit activation will occur when any of these operations are performed on a servant that is not currently active (that is, it is associated with no Object Id in the POA's Active Object Map). If the POA has the MULTIPLE_ID policy, the servant_to_reference and servant_to_id operations will always perform implicit activation, even if the servant is already associated with an Object Id.
- The servant_to_reference operation, which takes a servant parameter and returns a reference.
- The servant_to_id operation, which takes a servant parameter and returns an Object Id.
Location Transparency
The POA supports location transparency for objects implemented using the POA. Unless explicitly stated to the contrary, all POA behavior described in this specification applies regardless of whether the client is local (same process) or remote. For example, like a request from a remote client, a request from a local client may: cause object activation if the object is not active; may block indefinitely if the target object's POA is in the holding state; may be rejected if the target object's POA is in the discarding or inactive states; may be delivered to a thread-unaware object implementation; or may be delivered to a different object if the target object's servant manager raises the ForwardRequest exception. The Object Id and POA of the target object will also be available to the server via the Current object, regardless of whether the client is local or remote.
Copyright © 1998-2003, Novell, Inc. All rights reserved.