Applying C++, Patterns, and Components to Develop an IDL Compiler for CORBA AMI Callbacks

Applying C++, Patterns, and Components to Develop an IDL Compiler for CORBA AMI Callbacks Alexander B. Arulanthu Carlos O’Ryan and Douglas C. Schmidt...
Author: Barbra Harrison
3 downloads 0 Views 145KB Size
Applying C++, Patterns, and Components to Develop an IDL Compiler for CORBA AMI Callbacks Alexander B. Arulanthu

Carlos O’Ryan and Douglas C. Schmidt

[email protected] Department of Computer Science St. Louis, MO 63130

fcoryan,[email protected] Electrical & Computer Engineering University of California, Irvine

Michael Kircher

Anniruda Gokhale

[email protected] Siemens ZT Munich, Germany

[email protected] Lucent Technologies Murray Hill, NJ

2: poller

POLLING CLIENT

This article will appear in the March 2000 C++ Report magazine.

1 Introduction

4: get

To make informed choices among middleware alternatives, developers of distributed object systems should understand the patterns and components used to implement key features in CORBA ORBs. Recent Object Interconnection columns [1, 2, 3] have explored the features of the CORBA Messaging specification [4]. In this article, we describe key C++ features, patterns, and components used to implement an OMG IDL compiler that supports the Asynchronous Method Invocation (AMI) callback model defined in the CORBA Messaging specification. The CORBA Messaging specification defines two AMI programming models, the polling model and the callback model. In both models, only clients behave asynchronously, i.e., server applications do not change at all. These AMI models are outlined briefly below:

1: request operation(args)

P O L L E R

TARGET OBJECT

4

3: response

Figure 1: Polling Model for CORBA Asynchronous Twoway Operations Callback model: In this model, when a client invokes a twoway asynchronous operation on an object, it passes an object reference to a reply handler servant as a parameter, as shown in Figure 2. This object reference is not passed to the server, but instead is stored locally by the client ORB. When CALLBACK CLIENT

1: request operation(callback, args)

TARGET OBJECT

4

3: upcall 2: response

Polling model: In this model, each two-way AMI operation returns a Poller valuetype [5], which is very much like a C++ or Java object in that it has both data members and methods. Operations on a Poller are just local C++ method calls and not remote CORBA operation invocations. The polling model is illustrated in Figure 1. The client can use the Poller methods to check the status of the request so it can obtain a server’s reply. If the server hasn’t replied yet, the client can either (1) block awaiting its arrival or (2) return to the calling thread immediately and check back on the Poller to obtain the valuetypes when it’s convenient.

Figure 2: Callback Model for CORBA Asynchronous Twoway Operations the server replies, the client ORB receives the response and uses the reply handler servant provided by the client application to dispatch the response to the appropriate callback operation. This model requires client application developers to obtain and initialize a POA and to activate objects in the POA, which effectively makes the application behave as both a client and a server. 1

Reply handler servants are accessed via normal object references. Therefore, servants can be implemented in processes other than the client or the server involved in the original invocation. For instance, it’s possible for a reply handler servant to process “third-party” replies. The most common use-case, however, is for the original client to process the response.

applications affect only how clients are written, as described step-by-step below.

Step 1: Define the IDL interface and generate the stubs: Throughout this article, we’ll use the following Quoter IDL interface to illustrate how to use and implement the AMI CallIn general, the callback model is more efficient than the back model: polling model because the client need not invoke method calls module Stock on a valuetype repeatedly to poll for results. Moreover, the { interface Quoter { AMI callback model provides the following benefits compared // Two-way operation to retrieve current to alternative CORBA invocation models: // stock value. long get_quote (in string stock_name);

Simplified asynchronous programming model: AMI al}; lows operations to be invoked asynchronously using the static // ... invocation interface (SII). Using SII for AMI eliminates much }; of the tedium and complexity inherent in the dynamic invocation interface (DII)’s deferred synchronous model. In particAfter IDL interfaces are defined, they must be passed ular, DII requires programmers to insert parameters explicitly through an OMG IDL compiler, which generates a standard into Request objects, whereas the SII-generated stubs auto- set of C++ stubs and skeletons. For each two-way operation in mate and optimize [6] parameter. the IDL interface, an IDL compiler can generate the SMI and Improved quality of service: When implemented properly, AMI stubs that applications use to invoke operations. As discussed in [9], servers remain unchanged. Thus, the skeletons AMI can improve the scalability of CORBA applications. For instance, it minimizes the number of client threads that would generated by the IDL compiler are no different for AMI than for SMI, so we won’t describe them in this article. The stubs otherwise required to perform two-way synchronous method for asynchronous operations are different, however. In particuinvocations (SMI). In addition, AMI is important for real-time CORBA applications [7] because it helps to bound the amount lar, they are given the name of the corresponding synchronous operation, but with a sendc prefix prepended. of time spent in ORB operations, i.e., only the client processFor example, an IDL compiler that supports AMI would ing time has to be considered when sending a request. This degenerate the following pair of stubs for our Quoter interface: coupling of client processing time from server operation execution time helps to simplify real-time scheduling analysis [8].

// Usual SMI stub. CORBA::Long Stock::Quoter::get_quote (const char *stock_name) { /* IDL compiler-generated SMI stub code... */ }

The remainder of this article is organized as follows: Section 2 presents an example that illustrates the CORBA AMI callback programming model in more detail; Section 3 describes the C++ features, patterns, tools, and components used in TAO’s IDL compiler to implement the CORBA AMI callback model; and Section 4 presents concluding remarks.

// New AMI stub (described below). void Stock::Quoter::sendc_get_quote // ReplyHandler object reference (Stock::AMI_QuoterHandler_ptr, const char *stock_name) { /* IDL compiler-generated AMI stub code... */ }

In addition to having a slightly different name, the asynchronous sendc get quote operation has a different signature than the synchronous get quote operation. In particular, sendc get quote has no return value and is passed In this section, we review how the AMI callback model works an object reference to an application-defined subclass of the from the perspective of a CORBA/C++ application developer. following AMI QuoterHandler: The steps required to program CORBA AMI callbacks are similar to the development of any CORBA application, i.e., class AMI_QuoterHandler : Messaging::ReplyHandler OMG IDL interface(s) must be defined and client code must be public { written to use the generated stubs. Servers require no changes // Callback stub invoked by the client ORB // to dispatch the reply. to work with AMI, however, because they are unaware of virtual void get_quote (CORBA::Long ami_return_val) whether a client invokes operations synchronously or asyn{ /* IDL compiler-generated stub code... */ } chronously [1]. Thus, the changes required to support AMI };

2 Programming the CORBA AMI Callback Model

2

 Activation-per-AMI-call strategy: One way to distinguish separate AMI calls without requiring a separate object per-invocation is to explicitly activate the same servant multiple times in the client’s POA. As described in [10], each activation can be given a designated object id. The get quote callback method can then examine this object id to determine to which invocation the reply belongs to, as follows:

The AMI QuoterHandler is generated automatically by an AMI-enabled IDL compiler; it determines where the reply from the server will be dispatched. Note that the send get quote method doesn’t need a return value because the value of the stock will be passed back to the get quote callback operation defined by the AMI QuoterHandler shown above. For more information on the AMI callback mapping rules for OMG IDL to C++, please see [2].

using namespace PortableServer; class My_Async_Stock_Handler : public POA_Stock::AMI_QuoterHandler { public: // Save the Current pointer My_Async_Stock_Handler (Current_ptr current) : current_ (Current::_duplicate (current)) {}

2. Implement the reply handler servant: Next, a client programmer must implement the reply handler servant by subclassing from AMI QuoterHandler, as shown below: class My_Async_Stock_Handler : public POA_Stock::AMI_QuoterHandler { public: // Callback method prints stock value. virtual void get_quote (CORBA::Long ami_return_val) { cout get_quote (ami_return_val); [12] I. Pyarali, T. H. Harrison, and D. C. Schmidt, “Asynchronous Comple} tion Token: an Object Behavioral Pattern for Efficient Asynchronous Event Handling,” in Pattern Languages of Program Design (R. Martin, This skeleton performs the three steps outlined earlier. F. Buschmann, and D. Riehle, eds.), Reading, MA: Addison-Wesley, 1997. [13] E. Gamma, R. Helm, R. Johnson, and J. Vlissides, Design Patterns: Elements of Reusable Object-Oriented Software. Reading, MA: AddisonWesley, 1995.

4 Concluding Remarks The Asynchronous Method Invocation (AMI) callback model is an important feature that has been integrated into CORBA via the OMG Messaging specification [4]. A key aspect of AMI callbacks is that operations can be invoked asynchronously using the static invocation interface (SII). This feature avoids much of the complexity inherent in the dynamic invocation interface (DII)’s deferred synchronous model. In this article, we explain how an IDL compiler can be structured to support the CORBA AMI callback model. We also show how C++ languages features, such as inheritance and dynamic binding, can be guided by familiar design patterns, such as Visitor, Abstract Factor, and Strategy, to provide a very flexible and robust IDL compiler architecture that can adapt to changes not foreseen in the original design. These patterns allowed us to concentrate on implementing the new CORBA AMI callback features, rather than wrestling with internal IDL compiler design issues. In a subsequent article, we will discuss the various components an ORB should support in its run-time architecture to implement the AMI callback functionality. We’ll also show performance results that demonstrate the benefits of using AMI versus the SMI and DII deferred synchronous models.

[14] Object Management Group, The Common Object Request Broker: Architecture and Specification, 2.3 ed., June 1999. [15] S. Johnson, YACC - Yet another Compiler Compiler. Bell Laboratories, Murray Hill, N.J., Unix Programmers Manual ed. [16] A. Gokhale and D. C. Schmidt, “Principles for Optimizing CORBA Internet Inter-ORB Protocol Performance,” in Hawaiian International Conference on System Sciences, January 1998. [17] D. C. Schmidt, “GPERF: A Perfect Hash Function Generator,” C++ Report, vol. 10, November/December 1998. [18] I. Pyarali, C. O’Ryan, D. C. Schmidt, N. Wang, V. Kachroo, and A. Gokhale, “Applying Optimization Patterns to the Design of Realtime ORBs,” in Proceedings of the 5th Conference on Object-Oriented Technologies and Systems, (San Diego, CA), USENIX, May 1999. [19] BEA Systems, et al., CORBA Component Model Joint Revised Submission. Object Management Group, OMG Document orbos/99-07-01 ed., July 1999. [20] N. Wang, D. C. Schmidt, and S. Vinoski, “Collocation Optimizations for CORBA,” C++ Report, vol. 11, October 1999.

13