Previous Up Next

Chapter 16  CORBA Messaging

The CORBA Messaging specification encompasses three separate, but complementary, topics. Each of the topics are discussed in the following sections.

16.1  Quality of Service (Policy Objects)

The first version of CORBA did not define any portable way for programmers to specify what quality of service (QoS) they wanted in their applications. Instead, many CORBA vendors provided proprietary APIs for this purpose.

Over time, CORBA has matured to provide a mechanism for programmers to specify what QoS they want in their applications. In CORBA terminology, a QoS value is called a policy object. Policy objects were first introduced with the POA specification (Section 5.5). The POA specification initially defined 7 types of policy and separate operations for creating each of these 7 kinds of policy object. The OMG realized that the addition of new policies to CORBA would not be practical if each new policy required that a new operation be added to an existing interface because this would create a versioning nightmare. Instead, the Messaging specification (which was introduced after the POA specification) defined a more general-purpose mechanism for introducing new policies to CORBA. This mechanism involves the following:

The programming steps required to create a policy object have the drawback of being verbose, but offer two benefits.

The first benefit is that this creation mechanism is general-purpose. This means that it can deal with more policy types (both CORBA-compliant and vendor-proprietary policy types) that might be introduced in the future.

The second benefit concerns the fact that the use of some policy types has the side-effect of embedding extra information in IORs (Chapter 10) or service contexts (Section 11.6). The fact that there is an integer constant corresponding to each subtype of CORBA::Policy means that this compact integer value can be embedded inside the IORs and service contexts. Because of this, the use of policy objects does not incur a significant bandwidth overhead.

Aside from providing a general-purpose mechanism for defining policy types, the Messaging specification also defines some specific policy types that can be used to control the QoS for making remote calls. These policies include the following:

The Messaging specification also defines a service context (Section 11.6) that is used to propagate request- or reply-related policy values between clients and servers. It is important to note that if a client application specifies a timeout value for a remote request and the timeout occurs then the CORBA runtime system in the server can cancel the request only if the request is still queued up to be dispatched within the server; the server cannot cancel the request if it has already been dispatched to the target object.

16.2  Asynchronous Messaging Interface (AMI)

By default, IDL operations provide blocking call-and-reply semantics, that is, when a client application makes a remote call to an object in a server, the client blocks until the server sends back a reply. These semantics are suitable for many applications, but some applications can benefit from non-blocking call-and-reply semantics.

For a long time, developers had just two choices for obtaining non-blocking call-and-reply behavior:

  1. The client could create a new thread and get that thread to make a blocking call. In this way, the main thread of the client is not blocked. This approach cannot be used if the client application must be single-threaded. Also, even if a client can be multi-threaded, the overhead of thread creation means that this approach does not scale up to make a lot of non-blocking calls.
  2. The client could use the send_deferred() API of the DII (Section 15.4). However, the DII can be very tedious to use so programmers rarely wanted to use this approach. Also, with this approach, the client application had to periodically poll to check if the reply had come back. Polling can waste a lot of CPU time if it is done too frequently. On the other hand, infrequent polling can cause delays in processing replies.

CORBA has now matured to provide a different non-blocking call-and-reply mechanism, which is called Asynchronous Messaging Interface (AMI).

AMI is an optional part of CORBA and not all CORBA products support it. Also, AMI requires that additional operations be generated into proxy classes by the IDL compiler. Unfortunately, doing this would break binary portability of Java CORBA products. For this reason, no Java CORBA product can support AMI—at least, not until the IDL-to-Java mapping is updated to support AMI.1 For these reasons, if you are considering using AMI in a project then it is vitally important to check that the CORBA product you are using supports AMI.

If a CORBA product does support AMI then it works as follows:

It is important to note that both the callback and polling communication mechanisms are implemented entirely within the client-side ORB runtime system—a server application is unaware of, and is unaffected by, how a client has made a request.

It is also important to note that of the CORBA implementations that support AMI, most support the callback model but do not support the polling model. This is because most developers view the callback model as being superior to the polling model and so CORBA implementors have little motivation to implement the polling model.

16.3  Time Independent Invocations (TII)

GIOP (Chapter 11) is a synchronous protocol. This means that the asynchronous messaging infrastructure of CORBA must be layered on top of GIOP. For example, the callback and polling models (Section 16.2) are layered on top of GIOP by the CORBA runtime system in client applications. Another commonly desired aspect of a messaging system is time independent invocations (TII), which can be explained as follows. Let us assume that a client application sends a request to a server but then the client is killed before it receives the reply. TII means that the reply message is kept in some form of persistent storage until the client application is restarted and then the reply message is delivered to the client.

The CORBA Messaging specification provides TII by introducing another piece of infrastructure called message routers. A message router is a delegation server, that is, a server that receives an incoming message and delegates it (passes it on) to another application.

An IOR (Chapter 10) contains the contact details of an object. However, an IOR can optionally have a TaggedComponent (Section 10.2.3) that contains a sequence of embedded router IORs. The sequence of router IORs reflects the chain of delegation, from the first router to the next router and so on to the eventual target server. If a client uses such an IOR but the client does not have the relevant routing policies set then requests are sent in the normal manner, that is, direct to the object in the server. However, if the client does have the relevant routing policies set then the CORBA runtime system in the client uses a different mechanism to send requests: the client sends the request to the first router, and the IOR of a callback object is passed along with the request. Each router delegates the request message to the next router. Eventually, the last router sends the request to the target server. As far as the target server is concerned, the last router is its client, and so the server sends its reply message to this last router. The routers then pass the reply message back along the chain of routers. The router closest to the client then delivers the reply message by invoking the appropriate operation on the callback object provided by the originating client.

The “added value” provided by the routers is that each router can store request/reply messages in a persistent store, such as a database. If any process—the client, one of the routers or a server—dies during the delegation of request/reply messages then the persistent storage of the messages means that the delegation can continue when the dead process is restarted.

Several policies (Section 16.1) can be used to control the QoS of message delivery:

16.4  Further Reading

A very readable and more detailed overview of AMI can be found in some magazine articles [SV99a, SV99b].

There is one exception to this. The Java-based JacORB product has added experimental support for AMI. The experience gained by the JacORB development team in doing this is likely to be fed back into the OMG standardization process for enhancing the IDL-to-Java mapping in order to support AMI.
As will be mentioned soon, AMI is implemented entirely within the CORBA runtime system of the client application. Because of this, the reply message will always be sent from the server to the CORBA runtime system of the client from which the request originated; it is the CORBA runtime system in the client that then invokes the reply on the callback object, which can be in the same client process or in another application.

Previous Up Next