Previous Table of Contents Next


2.3.1.2. The ACE Framework Components

Around 40% of ACE consists of communication software framework components that integrate and enhance the C++ wrappers. These framework components support the flexible configuration of concurrent communication applications and services. The framework layer in ACE contains the following components:

  Event demultiplexing components. The ACE Reactor (Schmidt, 1995) and Proactor (Harrison, Pyarali, et al., 1997) are extensible, object-oriented demultiplexers that dispatch application-specific handlers in response to various types of I/O-based, timer-based, signal-based, and synchronization-based events.
  Service initialization components. The ACE Connector and Acceptor components (Schmidt, 1996b) decouple the active and passive initialization roles, respectively, from tasks that communication services perform once initialization is complete.
  Service configuration components. The ACE Service Configurator (Jain & Schmidt, 1997) supports the configuration of applications whose services can be assembled dynamically at installation time and/or runtime.
  Layered service stream components. The ACE Streams components (Schmidt & Suda, 1994) simplify the development of concurrent communication software applications (such as protocol stacks) composed of hierarchically layered services.
  ORB adapter components. ACE can be integrated seamlessly with single-threaded and multithreaded CORBA implementations via ORB adapters (Pyarali et al., 1996).

When combined with the use of C++ language features (such as templates, inheritance, and dynamic binding) and design patterns (such as Abstract Factory, Builder, and Service Configurator), the ACE framework components facilitate the development of communication software that can be updated and extended without modifying, recompiling, relinking, or even restarting running systems (Schmidt & Suda, 1994).

2.3.1.3. Self-Contained Distributed Service Components

ACE provides a standard library of distributed services that are packaged as self-contained components. Although these service components are not strictly part of the ACE framework, they play two important roles:

  Factoring out reusable distributed application building blocks. These service components provide reusable implementations of common distributed application tasks such as naming, event routing, logging, time synchronization, and network locking.
  Demonstrating common-use cases of ACE. These distributed services also demonstrate how ACE components (such as Reactors, Service Configurators, Acceptors and Connectors, active objects, and IPC wrappers) can be used effectively to develop flexible and efficient communication software.

2.3.1.4. Middleware Applications

ACE has been used in research and development projects at many universities and companies. For instance, it has been used to build avionics systems at McDonnell Douglas (Schmidt et al., 1997); telecommunication systems at Bellcore (Schmidt, 1995), Ericsson (Schmidt & Stephenson, 1995), and Motorola (Schmidt, 1996a); and medical imaging systems at Siemens (Jain & Schmidt, June 1997) and Kodak (Pyarali et al., 1996). In addition, ACE has been the subject of many academic research projects. Two examples of middleware applications provided with the ACE release are

  The ACE ORB (TAO; Schmidt et al., 1997), which is a real-time implementation of CORBA built using the framework components and patterns provided by ACE
  JAWS (Hu et al., 1997), which is a high-performance, adaptive Web server built using the components in ACE

2.4. Developing High-Performance Web Servers with Patterns and Framework Components

The benefits of applying frameworks and patterns to communication software are best introduced by example. This section describes the structure and functionality of high-performance Web servers developed using the patterns and framework components in ACE. Many error-handling details are omitted to keep the code examples concise. In addition, the examples focus on features that are portable across multiple OS platforms, although noteworthy platform-specific features of ACE (such as asynchronous I/O and I/O completion ports) are described where appropriate.

2.4.1. An Overview of a Web System

Figure 2.3 illustrates the general architecture of a Web system. The diagram provides a layered view of the architectural components required for an HTTP client to retrieve an HTML file from an HTTP server (Fielding, Gettys, Mogul, Frystyk, & Berners-Lee, 1997). Through GUI interactions, the client application user instructs the HTTP client to retrieve a file. The requester is the active component of the client that communicates over the network. It issues a request for the file to the server with the appropriate syntax of the transfer protocol—in this case, HTTP. Incoming requests to the HTTP server are received by the dispatcher, which is the request demultiplexing engine of the server. It is responsible for creating new threads or processes (for concurrent Web servers) or managing sets of socket handles (for single-threaded concurrent servers). Each request is processed by a handler, which goes through a life cycle of parsing the request, logging the request, fetching file status information, updating the cache, sending the file, and cleaning up after the request is done. When the response returns to the client with the requested file, it is parsed by an HTML parser so that the file can be rendered. At this stage, the requester can issue other requests on behalf of the client (e.g., in order to maintain a client-side cache).


FIGURE 2.3.  The general architecture of a Web system.


Previous Table of Contents Next