As with any container, you can think of the POA as having an external perspective and an internal perspective. The internal model of the POA is in terms of Servant objects: these are the objects that implement the user's business logic. The external model of the POA is in terms of
Object References, which are references that can be used in distributed system invocations (for example, these Object References are analogous to instances of
java.rmi.Remote in RMI/J2EE terminology, CORBA Object References in CORBA terminology, or instances of
MarshalByRefObject in .NET Remoting terminology). The task of the POA is to map between external Object References and internal Servant objects.
Servers can support multiple POAs. At least one POA must be present, which is called the Root POA. The Root POA is created automatically for you. The set of POAs is hierarchical; all POAs have the Root POA as their ancestor.
Servant Managers locate and assign Servants to objects for the POA. When an Object Reference is assigned to a Servant, it is called an
active object and the Servant is said to
incarnate the active object. Every POA has one
Active Object Map which keeps track of the object IDs of active objects and their associated active Servants.
|
|
|
|
|
|
|
Calls are processed on a distinguished main thread. Requests for all main-thread POAs are processed sequentially. In a multi-threaded environment, all calls processed by all POAs with this policy are thread-safe. The application programmer designates the main thread by calling ORB.Run() or ORB.PerformWork(). For more information about these methods, see “Activating objects”.
|
Typically, USER_ID is for persistent objects, and
SYSTEM_ID is for transient objects. If you want to use
SYSTEM_ID for persistent objects, you can extract them from the Servant or Object Reference.
The Bind Support policy (a VisiBroker-specific policy) controls the registration of POAs and active objects with the VisiBroker Smart Agent (osagent). If you have several thousands objects, it is not feasible to register all of them with the
osagent. Instead, you can register the POA with the
osagent. When a client request is made, the POA name and the object ID is included in the bind request so that the
osagent can correctly forward the request. The valid values for the Bind Support policy are listed in the following table.
The ResolveInitialReferences method returns a value of type
CORBA.Object. You are responsible for narrowing the returned object reference to the desired type, which is PortableServer.POA in the previous example.
A POA is created using CreatePOA on its parent POA. You can name the POA anything you like; however, the name must be unique with respect to all other POAs with the same parent. If you attempt to give two POAs the same name, a CORBA exception (
AdapterAlreadyExists) is raised.
The POA manager (<POAManager>) controls the state of the POA (for example, whether it is processing requests). If null is passed to
CreatePOA as the POA manager name, a new POA manager object is created and associated with the POA. Typically, you will want to have the same POA manager for all POAs. For more information about the POA manager, see
“Managing POAs with the POA manager”.
When Object References are associated with an active Servant, if the POA's Servant Retention Policy is RETAIN, the associated object ID is recorded in the Active Object Map and the object is activated. Activation can occur in one of several ways:
•
|
Explicit activation—The server application itself explicitly activates objects by calling ActivateObject or ActivateObjectWithId.
|
•
|
On-demand activation—The server application instructs the POA to activate objects through a user-supplied Servant Manager. The Servant Manager must first be registered with the POA through SetServantManager.
|
•
|
Implicit activation—The server activates objects solely by in response to certain operations. If a Servant is not active, there is nothing a client can do to make it active (for example, requesting for an inactive object does not make it active.)
|
•
|
Default Servant—The POA uses a single Servant to implement all of its objects.
|
By setting IdAssignmentPolicy.SYSTEM_ID on a POA, objects can be explicitly activated without having to specify an object ID. The server invokes
ActivateObject on the POA which activates, assigns and returns an object ID for the object. This type of activation is most common for transient objects. No Servant Manager is required since neither the object nor the Servant is needed for very long.
Objects can also be explicitly activated using object IDs. A common scenario is during server initialization where the user invokes ActivateObjectWithId to activate all the objects managed by the server. No Servant Manager is required since all the objects are already activated. If a request for a non-existent object is received, an
OBJECT_NOT_EXIST exception is raised. This has obvious negative effects if your server manages large numbers of objects.
testPoa.ActivateObjectWithId(managerId, managerServant);
•
|
Raise an OBJECT_NOT_EXIST exception that is returned to the client.
|
The POA policies determine any additional steps that may occur. For example, if RequestProcessingPolicy.USE_SERVANT_MANAGER and
ServantRetentionPolicy.RETAIN are enabled, the Active Object Map is updated with the Servant and object ID association. if
RequestProcessingPolicy.USE_SERVANT_MANAGER and
ServantRetentionPolicy.RETAIN are enabled, the Active Object Map is updated with the Servant and object ID association.
A Servant can be implicitly activated by certain operations if the POA has been created with ImplicitActivationPolicy.IMPLICIT_ACTIVATION,
IdAssignmentPolicy.SYSTEM_ID, and
ServantRetentionPolicy.RETAIN. Implicit activation can occur with:
If the POA has IdUniquenessPolicy.UNIQUE_ID set, implicit activation can occur when any of the above operations are performed on an inactive Servant.
If the POA has IdUniquenessPolicy.MULTIPLE_ID set,
ServantToReference and
ServantToId operations always perform implicit activation, even if the Servant is already active.
Use the RequestProcessing.USE_DEFAULT_SERVANT policy to have the POA invoke the same Servant no matter what the object ID is. This is useful when little data is associated with each object.
There are two types of Servant Managers: Servant Activator and
Servant Locator. The type of policy already in place determines which type of Servant Manager is used. For more information on POA policy, see
“POA policies”. Typically, a Servant Activator activates persistent objects and a Servant Locator activates transient objects.
To use Servant Managers, RequestProcessingPolicy.USE_SERVANT_MANAGER must be set as well as the policy which defines the type of Servant Manager (
ServantRetentionPolicy.RETAIN for Servant Activator or
ServantRetentionPolicy.NON_RETAIN for Servant Locator.)
ServantActivators are used when ServantRetentionPolicy.RETAIN and
RequestProcessingPolicy.USE_SERVANT_MANAGER are set.
The Etherealize and
Incarnate method implementations are user-supplied code.
At a later date, the Servant can be deactivated. This may occur from several sources, including the DeactivateObject operation, deactivation of the POA manager associated with that POA, and so forth. More information on deactivating objects is described in
“Deactivating objects”.
In many situations, the POA's Active Object Map could become quite large and consume memory. To reduce memory consumption, a POA can be created with RequestProcessingPolicy.USE_SERVANT_MANAGER and
ServantRetentionPolicy.NON_RETAIN, meaning that the Servant-to-object association is not stored in the Active Object Map. Since no association is stored, Servant Locator Servant Managers are invoked for each request.
2
|
Since ServantRetentionPolicy.NON_RETAIN is used, the POA does not search the Active Object Map for the object ID.
|
3
|
The POA invokes Preinvoke on a Servant Manager. Preinvoke passes the object ID, the POA in which the object is being activated, and a few other parameters.
|
The Preinvoke and
Postinvoke method implementations are user-supplied code.
By default, when a POA manager is created, it is in the Holding state. When the POA manager is in the
Holding state, the POA queues all incoming requests.
waitForCompletion is
Boolean. If
false, this operation returns immediately after changing the state to
Holding. If
true, this operation returns only when all requests started prior to the state change have completed or when the POA manager is changed to a state other than
Holding.
AdapterInactive is the exception raised if the POA manager was in the
Inactive state prior to calling this operation.
POA managers in the Inactive state cannot change to the
Holding state.
When the POA manager is in the Active state, its associated POAs process requests.
AdapterInactive is the exception raised if the POA manager was in the
Inactive state prior to calling this operation.
POA managers currently in the Inactive state can not change to the
Active state.
When the POA manager is in the Discarding state, its associated POAs discard all requests that have not yet started. In addition, the adapter activators registered with the associated POAs are not called. This state is useful when the POA is receiving too many requests. You need to notify the client that their request has been discarded and to resend their request. There is no inherent behavior for determining if and when the POA is receiving too many requests. It is up to you to set up thread monitoring if so desired.
The waitForCompletion option is
Boolean. If
false, this operation returns immediately after changing the state to
Holding. If
true, this operation returns only when all requests started prior to the state change have completed or when the POA manager is changed to a state other than
Discarding.
AdapterInactive is the exception raised if the POA manager was in the
Inactive state prior to calling this operation.
POA managers currently in the Inactive state can not change to the
Discarding state.
When the POA manager is in the Inactive state, its associated POAs reject incoming requests. This state is used when the associated POAs are to be shut down.
POA managers in the Inactive state cannot change to any other state.
After the state changes, if etherealizeObjects is
true, then all associated POAs that have
ServantRetentionPolicy.RETAIN and
RequestProcessingPolicy.USE_SERVANT_MANAGER set call
Etherealize on the Servant Manager for all active objects. If
etherealizeObjects is
false, then
Etherealize is not called. The
waitForCompletion option is
Boolean. If
false, this operation returns immediately after changing the state to
Inactive. If
true, this operation returns only when all requests started prior to the state change have completed or
Etherealize has been called on all associated POAs (that have
ServantRetentionPolicy.RETAIN and
RequestProcessingPolicy.USE_SERVANT_MANAGER).
AdapterInactive is the exception raised if the POA manager was in the
Inactive state prior to calling this operation.
•
|
iiop_tp: TCP transport with thread pool dispatcher
|
•
|
iiop_ts: TCP transport with thread per session dispatcher
|
•
|
iiop_tm: TCP transport with main thread dispatcher
|
To change the default server engine policy, enter its name using the vbroker.se.default property and define the values for all the components of the new server engine. For example:
The proxyHost property can also take an IP address as its value. Doing so replaces the default hostname in the IOR with this IP address.
Setting connectionMax to 0 (zero) indicates that there is no restriction on the number of connections, which is the default setting.
Setting connectionMaxIdle to 0 (zero) indicates that there is no timeout, which is the default setting.
Garbage collection time can also be specified for the Manager to garbage-collect idled connections. (Connections can idle after the connectionMaxIdle time until they are garbage-collected.) You can use the
garbageCollectTimer property to specify the period of garbage collection in seconds:
If you do not set the port property (or set it to 0 [zero]), a random port will be selected. A 0 value for the
proxyPort property means that the IOR will contain the actual port (defined by the
listener.port property or selected by the system randomly). If it is not required to advertise the actual port, set the proxy port to a non-zero (positive) value.
Further control is provided through the SCM for the ThreadPool dispatcher type. The
ThreadPool defines the minimum and maximum number of threads that can be created in the thread pool, as well as the maximum time in seconds after which an idled thread is destroyed. These values are controlled with the following properties:
Changing the default listener.port property is the simplest method, but this affects all POAs that use the default server engine. This may or may not be what you want.
An adapter activator supplies a POA with the ability to create child POAs on demand, as a side-effect of receiving a request that names the child POA (or one of its children), or when FindPOA is called with an activate parameter value of
true. A server that creates all its needed POAs at the beginning of execution does not need to use or provide an adapter activator; it is necessary only for the case in which POAs need to be created during request processing.
•
|
If the POA has ServantRetentionPolicy.RETAIN, the POA looks at the Active Object Map to locate a Servant associated with the Object ID from the request. If a Servant exists, the POA invokes the appropriate method on the Servant.
|
•
|
If the POA has ServantRetentionPolicy.NON_RETAIN or has ServantRetentionPolicy.RETAIN but did not find the appropriate Servant, the following may take place:
|
•
|
If the POA has RequestProcessingPolicy.USE_DEFAULT_SERVANT, the POA invokes the appropriate method on the default Servant.
|
•
|
If the POA has RequestProcessingPolicy.USE_SERVANT_MANAGER, the POA invokes Incarnate or Preinvoke on the Servant Manager.
|
•
|
If the POA has RequestProcessingPolicy.USE_OBJECT_MAP_ONLY, an exception is raised.
|