Flylib.com

Books Software

 
 
 

2.3 Summary

Ru-Brd

2.3 Summary

This chapter described two groups of design dimensions related to the successful development and deployment of networked applications. Service design dimensions affect the ways in which application services are structured, developed, and instantiated . Service configuration dimensions affect user or administrator abilities to vary the run-time placement and configuration of networked services after delivery and deployment.

Service design dimensions have a significant impact on how effectively applications use system and network resources. Efficient resource usage is closely linked to application response time, as well as to overall system performance and scalability. Performance is an important factor that's visible to end users. Though a coherent and modular design is less visible to end users, it's critical to a product's long- term success.

Good design simplifies maintenance and allows application functionality to evolve in response to market changes and competitive pressures without losing quality or performance. Fortunately, performance and modularity needn't be an either/or proposition. By carefully considering service design dimensions and applying ACE judiciously, you'll be able to create highly efficient and well-designed networked applications.

Even well-designed services and applications may need to adapt to a variety of deployment environments and user demands. Service configuration dimensions involve tradeoffs between design decisions associated with identifying a particular set of services and linking these services into the address space of one or more applications. To produce successful solutions, a networked application's flexibility must be weighed against its security, packaging, and complexity concerns.

When developing networked applications, the two sets of design dimensions in this chapter should be considered along with the dimensions described in Chapters 1 and 5 of C++NPv1. The ACE frameworks described in this book offer powerful tools to implement flexible and extensible designs with many combinations of tradeoffs and capabilities.

Ru-Brd
Ru-Brd

Chapter 3. The ACE Reactor Framework

C HAPTER S YNOPSIS

This chapter describes the design and use of the ACE Reactor framework. This framework implements the Reactor pattern [POSA2], which allows event-driven applications to react to events originating from a number of disparate sources, such as I/O handles, timers, and signals. Applications override framework-defined hook methods , which the framework then dispatch to process events. We show how to implement a logging server using a reactor that (1) detects and demultiplexes different types of connection and data events from various event sources and (2) then dispatches the events to application-defined handlers that process the events.

Ru-Brd
Ru-Brd

3.1 Overview

The ACE Reactor framework simplifies the development of event-driven programs, which characterize many networked applications. Common sources of events in these applications include activity on an IPC stream for I/O operations, POSIX signals, Windows handle signaling, and timer expirations. In this context, the ACE Reactor framework is responsible for

  • Detecting the occurrence of events from various event sources

  • Demultiplexing the events to their preregistered event handlers

  • Dispatching to hook methods defined by the handlers to process the events in an application-defined manner

This chapter describes the following ACE Reactor framework classes that networked applications can use to detect the occurrence of events and then demultiplex and dispatch the events to their event handlers:

ACE Class

Description

ACE_Time_Value

Provides a portable, normalized representation of time and duration that uses C++ operator overloading to simplify time- related arithmetic and relational operations.

ACE_Event_Handler

An abstract class whose interface defines the hook methods that are the target of ACE_Reactor callbacks. Most application event handlers developed with ACE are descendants of ACE_Event_Handler .

ACE_Timer_Queue

An abstract class defining the capabilities and interface for a timer queue. ACE contains a variety of classes derived from ACE_Timer_Queue that provide flexible support for different timing requirements.

ACE_Reactor

Provides the interface for managing event handler registrations and executing the event loop that drives event detection, demultiplexing, and dispatching in the Reactor framework.

The most important relationships between the classes in the ACE Reactor framework are shown in Figure 3.1. These classes play the following roles in accordance with the Reactor pattern [POSA2]:

Figure 3.1. The ACE Reactor Framework Classes

  • Event infrastructure layer classes provide application-independent strategies for synchronously detecting and demultiplexing events to event handlers and then dispatching the associated event handler hook methods. The infrastructure layer components in the ACE Reactor framework include ACE_Time_Value , ACE_Event_Handler , the ACE timer queue classes, and the various implementations of the ACE_Reactor .

  • Application layer classes define event handlers to perform application-defined processing in their hook methods. In the ACE Reactor framework, application layer classes are descendants of ACE_Event_Handler .

The power of the ACE Reactor framework comes from encapsulating the differences between event demultiplexing mechanisms available on various operating systems and maintaining a separation of concerns between framework classes and application classes. By separating application-independent event demultiplexing and dispatching mechanisms from application-dependent event processing policies , the ACE Reactor framework provides the following benefits:

  • Broad portability. The framework can be configured to use many OS event demultiplexing mechanisms, such as select() (available on UNIX, Windows, and many real-time operating systems), /dev/poll (available on certain UNIX platforms), and WaitForMultipleObjects() (available only on Windows).

  • Automates event detection, demultiplexing, and dispatching. By eliminating reliance on nonportable native OS event demultiplexing APIs, the ACE Reactor framework provides applications with a uniform object-oriented event detection, demulti-plexing, and dispatching mechanism. Event handler objects can be registered with the ACE_Reactor to process various types of events.

  • Transparent extensibility. The framework employs hook methods via inheritance and dynamic binding to decouple lower-level event mechanisms , such as detecting events on multiple I/O handles, expiring timers, and demultiplexing and dispatching methods of the appropriate event handler to process these events, from higher-level application event processing policies , such as connection establishment strategies, data marshaling and demarshaling, and processing of client requests . This design allows the ACE Reactor framework to be extended transparently without modifying existing application code.

  • Increase reuse and minimize errors. Developers who write programs using native OS event demultiplexing operations must reimplement, debug, and optimize the same low-level code for each application. In contrast, the ACE Reactor framework's event detection, demultiplexing, and dispatching mechanisms are generic and can therefore be reused by many networked applications. This separation of concerns allows developers to focus on high-level application-defined event handler policies, rather than wrestling repeatedly with low-level mechanisms.

  • Efficient event demultiplexing. The ACE Reactor framework performs its event demultiplexing and dispatching logic efficiently . For instance, the ACE_Select_Reactor presented in Section 4.2 uses the ACE_Handle_Set_Iterator wrapper facade class described in Chapter 7 of C++NPv1. This wrapper facade uses an optimized implementation of the Iterator pattern [GoF] to avoid examining fd_set bit-masks one bit at a time. This optimization is based on a sophisticated algorithm that uses the C++ exclusive-or operator to reduce run-time complexity from O(number of total bits) to O(number of enabled bits) , which can improve the run-time performance of large-scale applications substantially.

The remainder of this chapter motivates and describes the capabilities of each class in the ACE Reactor framework. We illustrate how this framework can be used to enhance the design of our networked logging server. If you aren't familiar with the Reactor pattern from POSA2, we recommend that you read about it first before delving into the detailed examples in this chapter. Chapter 4 then describes the design and use of the most common implementations of the ACE_Reactor interface presented here. That chapter also describes the various concurrency models supported by these ACE_Reactor implementations.

Ru-Brd