Previous Up Next

Chapter 6  POA Policies

Section 5.6 discussed several different kinds of POA, such as “simple”, “lazy loader”, “cache” and “default servant”. However, that section did not explain how to create a POA of a specific kind. How to create a POA of a specific kind is the topic of this chapter.

CORBA uses the term policy to mean quality of service (QoS). A POA is created by calling the create_POA() operation. One of the parameters to this operation is a sequence of policy objects. Section 6.1 discusses the different sub-types of Policy object that are available, and how some of them combine together to create different kinds of POA. Finally, Section 6.2 briefly outlines the APIs that are used to create a policy object.

6.1  Available POA Policies

Some of the POA policies determine what kind of POA is created; these policies are discussed in Section 6.1.1. Some other POA policies are used to specify other QoS offered by the POA, and these are discussed in Sections 6.1.26.1.6.

6.1.1  Policies that Determine the POA’s Kind

A policy object is a “wrapper” around an enum value. In this section, I discuss the enum values; a discussion of how to create object wrappers around these values is deferred until Section 6.2.

The following three enum types, when combined together, determine a POA’s kind:


enum ServantRetentionPolicyValue {RETAIN, NON_RETAIN};
enum IdUniquenessPolicyValue {UNIQUE_ID, MULTIPLE_ID};
enum RequestProcessingPolicyValue
	                      {USE_ACTIVE_OBJECT_MAP_ONLY,
	                       USE_DEFAULT_SERVANT,
	                       USE_SERVANT_MANAGER};

The first enum determines whether or not object ids are retained in the POA by an active object map (AOM). Many developers find these enum values difficult to remember. More meaningful names might have been HAS_AN_AOM and DOES_NOT_HAVE_AN_AOM instead of RETAIN and NON_RETAIN, respectively.

The second enum determines whether there is a one-to-one mapping (the UNIQUE_ID value) or a many-to-one mapping (MULTIPLE_ID) between object ids and servants. The MULTIPLE_ID policy allows one servant to represent many CORBA objects. You must use the MULTIPLE_ID policy for the “default servant” POA kind (Section 5.6.4). For the other kinds of POA, you can use either policy, but the UNIQUE_ID policy is what is desired most of the time.

The third enum determines whether the POA has an AOM, a default servant and/or a servant manager:

6.1.2  Multi- and Single-threaded Policy Values

The following enum is used to specify how a POA utilizes threads to dispatch incoming requests:


enum ThreadPolicyValue  {ORB_CTRL_MODEL,
	                         SINGLE_THREAD_MODEL,
	                         MAIN_THREAD_MODEL};

These policy values are discussed in the following sub-subsections.

6.1.2.1  The ORB_CTRL_MODEL Policy Value

The ORB_CTRL_MODEL policy specifies that the ORB runtime system has control over how incoming requests are dispatched. This policy value has very under-specified semantics:

The under-specified semantics of ORB_CTRL_MODEL hinder the portability of CORBA applications. Many people hope that the OMG will add better-defined multi-threading policy values in the future.

6.1.2.2  The SINGLE_THREAD_MODEL and MAIN_THREAD_MODEL Policy Values

You would think that the SINGLE_THREAD_MODEL policy would have obvious semantics. However, it is actually ambiguous:

When the OMG became aware of this ambiguity, they resolved it by declaring that SINGLE_THREAD_MODEL had the latter set of semantics, and they introduced a new enum value, called MAIN_THREAD_MODEL that had the first set of semantics.

Readers should note that some CORBA products that ascribed the “wrong” semantics to SINGLE_THREAD_MODEL have not yet added support for the (newer) MAIN_THREAD_MODEL policy value. For this reason, it is important to carefully read the documentation of a CORBA product to check what semantics it provides for SINGLE_THREAD_MODEL POAs.

6.1.3  Policy Values for Object Lifetimes and Naming

The following enum types are used to specify the lifetimes of objects and how they are assigned object ids:


enum LifespanPolicyValue {TRANSIENT, PERSISTENT};
enum IdAssignmentPolicyValue {USER_ID, SYSTEM_ID};

CORBA uses the term transient to mean temporary. Thus, the TRANSIENT policy value specifies that object references (for objects within the POA) are valid only for the duration of the server process. In other words, the object references are not valid if the server is killed and restarted. How a CORBA product enforces this is an implementation detail, but it is typically done by embedding a timestamp into IORs. The CORBA runtime system can use this timestamp information to differentiate between references to objects that are “similar” but have been created in different runs of a server process.

The PERSISTENT policy value specifies that object references (for objects within the POA) are valid even if the server is killed and restarted.

It is important to note that the TRANSIENT and PERSISTENT policies determine the lifetimes of object references. These policies do not determine whether data associated with an object is maintained in volatile RAM or in a persistent store, such as a file or database. The following are typical examples of how these policy values are used:

In CORBA terminology, programmers are referred to as users. Hence, the USER_ID policy value indicates that the programmer specifies the object id when activating (inserting) a servant into a POA. In this case, the programmer uses the activate_object_with_id() operation, as shown below:


poa.activate_object_with_id(obj_id, sv);

The SYSTEM_ID policy indicates that the CORBA runtime system picks a unique object id when a servant is activated into a POA. In this case, the programmer uses the activate_object() operation, as shown below:


obj_id = poa.activate_object(sv);

Technically, the TRANSIENT and PERSISTENT policies are independent of the USER_ID and SYSTEM_ID policies. However, PERSISTENT is almost always combined with USER_ID, for the following reasons:

The TRANSIENT policy is usually combined with SYSTEM_ID because programmers are rarely concerned with assigning meaningful names to temporary objects.

6.1.4  Transactional Object Policy Values

Some client-server systems require the ability for a database transaction to span multiple operation calls from a client to one server and/or the ability for a transaction to span multiple databases. Such client-server interactions require use of the CORBA Object Transaction Service (OTS), which is discussed in Chapter 21.

A POA policy is used to indicate whether or not the objects within that POA can take part in distributed transactions.1 The policy can have one of the following values:

REQUIRES
This policy value indicates that all invocations on objects within the POA must be part of a transaction.2
FORBIDS
This policy value indicates that all invocations on objects within the POA must not be part of a transaction.
ADAPTS
This policy value indicates that objects are sensitive to the presence or absence of a transaction and can “adapt” to either style of invocation.

6.1.5  Implicit and Explicit Activation Policy Values

Most policy values used with POAs have some effect that either is visible to clients or affects the high-level architecture of the server program. The ImplicitActivationPolicyValue is different in that it controls a relatively minor aspect of coding a server.


enum ImplicitActivationPolicyValue
	       {IMPLICIT_ACTIVATION, NO_IMPLICIT_ACTIVATION};

To make a servant represent a CORBA object requires three steps:

  1. You create a servant.
  2. You activate (insert) the servant into a POA.
  3. You call _this() on the servant to obtain the object reference of the CORBA object that it represents.

If you use the NO_IMPLICIT_ACTIVATION policy then you must execute all three steps. However, if you use the IMPLICIT_ACTIVATION policy then you can optionally omit step 2 because step 3 will implicitly activate the servant if it is not already activated. So the benefit of IMPLICIT_ACTIVATION is that can optimize away one line of code associated with the creation of CORBA objects. This is a relatively minor benefit, and many people have religious feelings over whether the IMPLICIT_ACTIVATION policy is a good policy or one to be avoided. On the one hand, some people like being able to optimize away a line of code in several places within a server application. On the the hand, the steeper learning curve associated with yet-another policy value arguably outweighs this benefit.

Note that if you use IMPLICIT_ACTIVATION then you must combine it with SYSTEM_ID.

6.1.6  Proprietary Policy Values

The preceding subsections have discussed CORBA-compliant policy values that can be used when creating POAs. A CORBA product is allowed to define additional, proprietary policies. Some CORBA products do this in order to give programmers greater control over choosing the QoS offered by objects. You have to consult the documentation of a particular CORBA product to find out what, if any, proprietary policies it provides.

6.2  Creating Policy Objects and POAs

Policy objects were first introduced with the POA specification. The POA specification initially defined 7 types of policy and defined a separate operation for creating each of these 7 kinds of policy object. For example, you can create a ThreadPolicy object by invoking the following operation on an existing POA:


ThreadPolicy create_thread_policy(
	                       in ThreadPolicyValue value);

The parameter to this operation is an enum value, and the operation creates a (subtype of) policy “wrapper” around it.

Having defined the POA specification, the OMG then realized that the concept of policy objects could be applied to other parts of CORBA too. However, having to add a new create-style operation to an existing interface for each new type of policy would create a versioning problem. Because of this, the OMG decided to define a “generic” API that could be used to create any kind of policy object. The work on defining this generic API was performed as part of CORBA Messaging (Chapter 16). Creation of transactional policy values (Section 6.1.4) is performed using this newer, generic API.

Overall, the CORBA APIs for creating POA policy objects and then using these to create POAs are quite verbose. The Creation of POA Hierarchies Made Simple chapter of the CORBA Utilities package [McH] discusses a utility class (available in C++ and Java) that dramatically reduces the amount of code required to create POAs.


Previous Up Next