<<

A Family of Design Patterns for Application-Level Gateways

Douglas C. Schmidt [email protected]

http://www.cs.wustl.edu/schmidt/ Department of Computer Science Washington University, St. Louis 63130 (TEL) 314-935-7538, (FAX) 314-935-7302

This paper appeared in the journal Theory and Practice of among software solutions for different applications in the Object Systems, special issue on Patterns and Pattern Lan- same domain. guages, Wiley & Sons, Vol. 2, No. 1, December 1996. Capturing and articulating the essence and commonality of successful communication software is important for several reasons: Abstract

 It helps guide the design choices of developers who Abstract are building new communication systems ± By under- standing the potential traps and pitfalls in their domain, developers can select suitable architectures, protocols, Developers of communication software must confront recur- and platform features without wasting time and effort ring design challenges involving robustness, ef®ciency, and implementing inef®cient or error-prone solutions. extensibility. Many of these challenges are independent of the application-speci®c requirements. Successful developers  It preserves important design information for program- resolve these challenges by applying appropriate design pat- mers who enhance and maintain existing software ± terns. However, these patterns have traditionallybeen locked Often, this information is locked in the minds of the in the minds of expert developers or buried within complex original developers. If this design information is not system source code. The primary contribution of this pa- documented explicitly, however, it will be lost over per is to describe a family of design patterns that underly time, thereby increasing maintenance costs and decreas- many object-oriented communication software systems. In ing software quality. addition to describing each pattern separately, the paper il- The purpose of this paper is to illustrate an effective way to lustrates how knowledge of the relationships and trade-offs document the essence of successful communication software among patterns helps guide the construction of reusable com- by describing key design patterns used to build application- munication software frameworks. level Gateways, which route messages between Peers dis- tributed throughout a communication system. Design patterns represent successful solutions to problems 1 Introduction that arise when building software [1]. Capturing and articu- lating key design patterns helps to enhance software quality Building,maintaining,and enhancing high quality communi- by addressing fundamental challenges in large-scale system cation systems is hard. Developers must have a deep under- development. These challenges include communication of standing of many complex issues such as service initializa- architectural knowledge among developers; accommodating tion and distribution, concurrency control, ¯ow control, error new design paradigms or architectural styles; resolving non- handing, and event loop integration. Successful communi- functional forces such as reusability, portability, and exten- cation software created by experienced software developers sibility; and avoiding development traps and pitfalls that are embodies solutions to these issues. usually learned only by costly trial and error. It is often dif®cult, however, to separate the essence of This paper presents the object-oriented architecture and successful software solutions from the details of a particular design of an application-level Gateway in terms of implementation. Even when software is written using well- the design patterns used to guide the construction of structured object-oriented frameworks and components, it reusable and Gateway-speci®c frameworks and compo- can be hard to identify key roles and relationships. More- nents. Application-level Gateways have stringent require- over, OS platform features (such as the absence or presence ments for reliability, performance, and extensibility. There- of multi-threading) or requirements (such as best-effort vs. fore, they are excellent exemplars for presenting the struc- fault tolerance error handling) are often different. These dif- ture, participants, and consequences of key design patterns ferences can mask the underlying architectural commonality that appear in many communication software systems.

1 PEERS : Output PEERS : Map : Routing : Input Channel Manager Table Channel : Message : SOCK Queue : SOCK 5: recv_msg() Stream Stream

1: send : Reactor send_ _msgmsg() 2: recv_recv_msgmsg()() : Output () 3: route_route_msgmsg()() : Input Channel Channel : Connector : Acceptor : Message msg()() : SOCK Queue : SOCK Stream 4: send_msgsend_ : SOCK : Map Stream Manager : SOCK Connector Acceptor GATEWAY OUTGOING INCOMING GATEWAY MESSAGES MESSAGES CONNECTION CONNECTION REQUEST REQUEST Figure 1: The Structure and Collaboration of Peers and the Gateway

The patterns described in this paper were discovered while building a wide range of communication systems including Figure 2: The Object-Oriented Gateway Software Archi- on-line transaction processing systems, telecommunication tecture switch management systems [2], electronic medical imag- ing systems [3], and parallel communication subsystems [4]. architecture for application-level Gateways.1 This architec- Although the speci®c application requirements in these sys- ture is based on extensive experience developing connection- temswerequitedifferent, thecommunication softwaredesign oriented Gateways for various commercial and research com- challenges were very similar. Therefore, although the exam- munication systems. After building multiple Gateway sys- ples in this paper focus on Gateways, the patterns embody tems it became clear that the software architecture of these design expertise that can be reused broadly in the communi- systems was largely independent of the protocols used to cation domain. route messages to Peers. This realization enabled the compo- The remainder of this paper is organized as follows: Sec- nents depicted in Figure 2 to be reused for the communication tion 2 outlines an object-oriented software architecture for software subsystems of many other projects. The ability to application-level Gateways; Section 3 examines the design reuse these components so widely stems from two factors: patterns that form the basis for reusable communication soft-

ware, using application-level Gateways as an example; Sec-  Understanding the actions and interactions of key de- tion 4 compares these patterns with those described in related sign patterns within the domain of communication soft- work; and Section 5 presents concluding remarks. ware: Patterns capture the structure and collaboration of participants in a software architecture at a higher level than source code and object-oriented design models that focus on individual objects and classes. Some of the communication 2 An Object-Oriented Software Archi- software patterns described in this paper have been docu- tecture for Application-level Gate- mented individually [7, 8, 9]. Although individual pattern descriptions capture valuable design expertise,complex com- ways munication software systems embody scores of patterns. Un- derstanding the relationships among these patterns is essen- This paper examines framework components and design pat- tial to document, motivate, and resolve dif®cult challenges terns that comprise and motivate the object-oriented architec- that arise when building communication software. There- ture of application-level Gateways developed by the author fore, Section 3 describes the interactions and relationships and his colleagues. A Gateway is a Mediator [1] that de- among these patterns in terms of a family of design patterns couples cooperating Peers throughout a network and allows for communication software. These design patterns work them to interact without having direct dependencies on each together to solve complex problems within the domain of other [5]. As shown in Figure 1, messages routed through communication software. the Gateway contain payloads encapsulated in routing mes- sages. 1Relationships between components are illustrated throughoutthis paper using Booch notation [6]. In this ®gure solid clouds indicate objects; nesting Figure 2 illustrates the structure, associations, and internal indicates composition relationships between objects; and undirected edges and external collaborations among objects within a software indicate an association exists between two objects.

2  Developing an object-oriented framework that imple- To increase system ¯exibility, connections can be estab- ments these design patterns: Recognizing the patterns lished in two ways: that commonly occur in many communication software sys- 1. From the Gateway to the Peers ± which is typically tems helped shape the development of reusable framework done whenever the Gateway ®rst starts up to establish components. The Gateway systems this paper is based the initial system con®guration of Peers; upon were implemented with the ADAPTIVE Communica- tion Environment (ACE) software [10]. ACE provides an 2. From a Peer to the Gateway ± which is typicallydone integrated framework of reusable C++ wrappers and compo- once the system is running whenever a new Peer wants nents that perform common communication software tasks. to send or receive routing messages. These tasks include event demultiplexing, event handler dis- In a large system, several scores of Peers may be con- patching, connection establishment, routing, dynamic con- nected to a single Gateway. Therefore, to expedite initial- ®guration of application services, and concurrency control. ization, the Gateway's Connector can initiate all con- In addition, the ACE framework contains implementations of nections asynchronously rather than synchronously. Asyn- the design patterns described in Section 3. However, the pat- chrony helps decrease connection latency over long delay terns are much richer than their implementation in ACE and paths (such as wide-area networks (WANs) built over satel- have been applied by many other communication systems, as lites or long-haul terrestrial links). The underlying SOCK well. Connector [11] contained within a Connector provides the low-level asynchronous connection mechanism. When a This section describes how various ACE components have SOCK Connector connects two socket endpoints via TCP been reused and extended to implement the application- it produces a SOCK Stream object, which is then used to independent and application-speci®c components in the com- exchange data between that Peer and the Gateway. munication Gateway shown in Figure 2. Following this

 Event demultiplexing components: The Reactor is overview, Section 3 examines the family of design patterns an object-oriented event demultiplexing mechanism based that underly the ACE components. on the [7] described in Section 3.1. It chan- nels all external stimuli in an event-driven application to a 2.1 Application-independent Components single demultiplexing point. This permits single-threaded applications to wait on event handles, demultiplex events, Most of the components in Figure 2 are based on ACE and dispatch event handlers ef®ciently. Events indicate that components that can be reused in other communication sys- something signi®cant has occurred (e.g., the arrival of a new tems. The only components that are not widely reusable connection or work request). The main source of events in are the Input and Output Channels, which implement the Gateway is routing messages that encapsulate various the application-speci®c details related to message formats payloads (such as commands, status messages, and bulk data and the routing protocol. The behavior of the application- transmissions). independent components in the Gateway is outlined below:

 Message demultiplexing components: The Map

 Interprocess communication (IPC) components: The Manager is a parameterized collection that ef®ciently maps SOCK Stream, SOCK Connector,andSOCK Acceptor external ids (e.g., Peer routing addresses) onto internal ids components encapsulate the socket network programming (e.g., Output Channels). The Gateway uses a Map interface [11]. These components simplify the development Manager to implement a Routing Table that handles of portable and correct communication software by shielding the demultiplexing and routing of messages internally to a developers from low-level, tedious, and error-prone socket- Gateway.TheRouting Table maps addressing infor- level programming. In addition, they form the foundation mation contained in routing messages sent by Peers to the for the higher-level ACE components and patterns described appropriate set of Output Channels. below.

 Message queueing components: The Message

 Service initialization components: The Connector Queue [10] provides a generic queueing mechanism. This and Acceptor are factories [1] that implement active mechanism runs ef®cient and robustly in multi-threaded or and passive strategies for initializing network services, single-threaded environments. Developers can select the de- respectively.2 These components are based on the Connec- sired concurrency strategy at the time a queue is instanti- tor pattern described in Section 3.2 and Acceptor pattern ated, The Gateway uses Message Queues to buffer mes- described in Section 3.3. The Gateway uses these com- sages in Output Channels while they are being routed ponents to establish connections with Peers and produce to Peers. initialized Input and Output Channels.

2Establishing connections between endpoints involves two roles: the 2.2 Application-speci®c Components passive role (which initializes an endpoint of communication at a particular Only two of the components (Input and Output address and waits passively for the other endpoint to connect with it) and the active role (which actively initiates a connection to one or more endpoints Channels) in Figure 2 are speci®c to the Gateway ap- that are playing the passive role). plication. These components implement the Router pattern

3 described in Section 3.4. Input and Output Channels reside in the Gateway, where they serve as proxies for the original source and the intended destination(s) of routing SOCK Svc Stream messages sent to hosts across the network. The behavior of Handler these two Gateway-speci®c components is described be- low: Message  Input Channels: Input Channels are responsible Queue Input for routing incoming messages to their destination(s). The Output Channel Channel Reactor noti®es an Input Channel when it detects an event on that connection's communication endpoint. The Input Channel then receives and frames a routing mes- Figure 3: Channel Inheritance Hierarchy sage from that endpoint, consults the Routing Table to determine the set of Output Channel destinations for the message, and requests the selected Output Channels to different connection than data sent from the Gateway to forward the message to the appropriate Peer destinations. the Peer. There are several advantages to separating input connections from output connections in this manner:

 Output Channels: An Output Channel is respon- sible for reliably delivering routing messages to their desti-  It simpli®es the construction of Gateway Routing nations. It implements a ¯ow control mechanism to buffer Tables; bursts of routing messages that cannot be sent immediately

 It allows more ¯exibility in connection con®guration due to transient network congestion or lack of buffer space at and concurrency strategies; a receiver. Flow control is a transport layer mechanism that ensures a source Peer does not send data faster than a desti-  It enhances reliability if errors occur on a connection nation Peer can buffer and process the data. For instance, if since Input and Output Channels can be recon- a destination Peer runs out of buffer space, the underlying nected independently. TCP protocol instructs the associated Gateway's Output Channel to stop sending messages until the destination Peer consumes its existing data. 3 A Family of Design Patterns for A Gateway integrates the application-speci®c and Application-level Gateways application-independent components by inheriting from, in- stantiating, and composing the ACE components described Section 2 illustrates the structure and functionality of an above. As shown in Figure 33 Input and Output application-level Gateway. Although this architectural Channels inherit from a common ancestor: the ACE Svc overview helps to clarify the behavior of key components Handler class, which is produced by Connectors and in a Gateway, it does not reveal the deeper relationships Acceptors.TheSvc Handler is a local Proxy [1] for and roles that underly the various software components. In a remotely connected Peer. It provides a SOCK Stream, particular, the architecture descriptions do not motivate why which enables Peers to exchange messages via connected a Gateway is designed in this particular manner or why Channels. certain components act and interact in certain ways. Under- An Output Channel uses an ACE Message Queue standing these relationships and roles is crucial to develop, to chain unsent messages in the order they must be deliv- maintain, and enhance communication software. ered when ¯ow control mechanisms permit. Once a ¯ow An effective way to capture and articulate these relation- controlled connection opens up, the ACE framework noti®es ships and roles is to describe the design patterns that reify its Output Channel, which starts draining the Message them. A is a recurring solution to a design Queue by sending messages to the Peer. If ¯ow control problem within a particular domain (such as business data occurs again this sequence of steps is repeated until all mes- processing, telecommunications, graphical user interfaces, sages are delivered. databases, or distributed communication software). Study- ing the patterns in Gateway software is important to: To improve reliability and performance, the Gateways described in this paper utilize the Transmission Con- 1. Identify successful solutions to common design chal- trol Protocol (TCP). TCP provides a reliable, in-order, lenges ± The patterns underlying the Gateway archi- non-duplicated bytestream service for application-level tecture transcend the particular details of the application Gateways. Although TCP connections are inherently bi- and resolve common challenges faced by communica- directional, data sent from Peer to the Gateway use a tion software developers. A thorough understanding of the patterns presented below enables widespread reuse 3 This ®gure illustrates additional Booch notation. Dashed clouds indicate of Gateway software architecture in other systems, classes; directed edges indicate inheritance relationships between classes; and an undirected edge with a small circle at one end indicates either a even when reuse of its algorithms, implementations, in- composition relation between two classes. terfaces, or detailed designs is not feasible [12].

4 These ®ve patterns are strategic because they signi®cantly in¯uence the software architecture for applications in a par- Router ticular domain (in this case, the domain of communication software and Gateways). For example, the Router pattern Acceptor described in Section 3.4 decouples input mechanisms from output mechanisms to ensure that message processing is not Active disrupted or postponed inde®nitely when a Gateway expe- Connector Object riences congestion or failure. This pattern helps to ensure a consistently high quality of service for Gateways that use reliable transport protocols such as TCP/IP or IPX/SPX. A Reactor thorough understanding of the strategic communication pat- STRATEGIC terns described in this paper is essential to develop robust, PATTERNS ef®cient, and extensible application-level Gateways. TACTICAL Application-level Gateways also utilize many tactical pat- PATTERNS terns, such as the following: Template Iterator Builder Proxy Adapter

Method  ± which provides a factory for building complex objects incrementally. The Gateway uses this pattern to create its Routing Table from a con®gu- Figure 4: The Family of Patterns for Application-level ration ®le. Gateways

 ± which decouples sequential access to a container from the representation of the container. 2. Reduce the effort of maintaining and enhancing The Gateway uses this pattern to connect and initialize Gateway software ± The use of patterns helps to cap- Input and Output Channels with Peers. ture and motivate the collaboration between multiple

 ± which speci®es an algorithm classes and objects. This is important for developers where some steps are supplied by a derived class. The who must maintain and enhance a Gateway. Although Gateway uses this pattern to selectively override cer- the roles and relationships in a Gateway design are tain steps in the Connector and Acceptor in order embodied in the source code, extracting them from the to restart failed connections automatically. surrounding implementation details can be costly and error-prone.  ± which transforms a non-conforming interface into one that can be used by a client. The Figure 4 illustrates the following strategic patterns related Gateway uses this pattern to treat different types of to connection-oriented, application-level Gateways: routing messages (such as commands, status informa- tion, and bulk data) in a uniform manner.

 Concurrency patterns:

 ± which provides a local surrogate object that acts in place of a remote object. The Gateway uses

 The Reactor pattern ± which decouples event demul- tiplexing and event handler dispatching from services this pattern to shield the main Gateway routing code performed in response to events; from delays or errors caused by the fact that Peers are located on other host machines in the network.

 The pattern ± which decouples method execution from method invocation. Compared to strategic patterns (which are often domain- speci®c and have broad design implications), tactical pat- terns are domain-independent and have a relatively localized

 Service initialization patterns: impact on a . For instance, Iterator is a tac- Gateway  The Connector pattern ± which decouples active service tical pattern used in the to process entries in the initialization from the tasks service performed once the Routing Table sequentially without violating data en- service is initialized; capsulation. Although this pattern is domain-independent and thus widely applicable, the problem it addresses does

 The Acceptor pattern ± which decouples passive service not impact the application-level Gateway software design as initialization from the tasks performed once the service pervasively as strategic patterns like the Router. A thorough is initialized. understanding of tactical patterns is essential to implement highly ¯exible software that is resilient to changes in appli-

 Application-speci®c patterns: cation requirements and platform environments. Although there are various forms for describing patterns,  The Router pattern ± which decouples input mecha- they typically convey the following information [1]: nisms from output mechanisms to route data correctly

without blocking a Gateway.  The intent of the pattern;

5 callback : select (handles) main Concrete reactor : APPLICATION Concrete foreach h in handles loop APPLICATION Event program Event_Handler Reactor : Handles table[h]->handle_event (type) Reactor() end loop Handler INITIALIZE MODE register_handler(callback) REGISTER HANDLER - SPECIFIC - INITIALIZATION get_handle() INDEPENDENT EXTRACT HANDLE handle_events() RUN EVENT LOOP Reactor select() 1 WAIT FOR EVENTS handle_events() MODE handle_event(event_type) n DISPATCH HANDLER(S) register_handler(eh, type) EVENT HANDLING remove_handler(eh, type) Event Handler 1 1 handle_event(type) Figure 6: Object Interaction Diagram for the Reactor Pattern 1 get_handle() n Handles A threading, synchronization, or locking within an appli- cation is often eliminated. Figure 5: Structure and Participants in the Reactor Pattern 2. The need to extend application behavior without requir- ing changes to the event dispatching framework ±The Reactor factors out the demultiplexing and dispatching

 The design forces that motivate and shape the pattern; mechanisms from the event handler processing poli-

 The solution to these forces; cies. The demultiplexing and dispatching mechanisms are generally independent of an application and are thus

 The related classes and their roles in the solution; reusable. In contrast, the event handler policies are more

 The responsibilities and dynamic collaborations among speci®c to an application. This separation of concerns classes; allows application policies to change without affecting

 The positive and negative consequences of using the the lower-level framework mechanisms. pattern;

 Guidance for implementors of the pattern; Structure, Participants, and Implementation: Figure 5

 Example source code illustrating how the pattern is ap- illustrates the structure and participants in the Reactor pat- plied; tern. The Reactor de®nes an interface for registering, removing, and dispatching Concrete Event Handler

 References to related work. objects (such as Input or Output Channels in the It is important to recognize that the strategic patterns in this Gateway). An implementation of this interface provides paper are much more generally applicable than the speci®c a set of application-independent mechanisms. These mech- use cases for the Gateway described below. The references anisms perform event demultiplexing and dispatching of [7, 8, 9] provide additional use cases for these patterns, along application-speci®c event handlers in response to events with more detailed coverage of each pattern and sample im- (such as input, output, signal, and timer events). plementations. An Event Handler speci®es an abstract interface used by the Reactor to dispatch callback methods 3.1 The Reactor Pattern de®ned by objects that register to events of interest. Each Concrete Event Handler selectively imple- Intent: The Reactor pattern decouples event demultiplex- ments callback method(s) to process events in an application- ing and event handler dispatching from the services per- speci®c manner. formed in response to events. Collaborations: Figure 6 illustrates the collaborations be- Motivation and Forces: Single-threaded applications tween participants in the Reactor pattern. These collabora- must be able to handle events from multiple sources without tions are divided into the following two modes: blocking on any single source. The Reactor pattern resolves the following forces that impact the design of single-threaded, 1. Initialization mode ±whereConcrete Event event-driven communication software: Handler objects are registered with the Reactor; 2. Event handling mode ±wheretheReactor invokes 1. The need to demultiplex multiple types of events from upcalls on registered objects, which then handle events multiple sources of events ef®ciently within a single in an application-speci®c way. thread of control ± A Reactor serializes the handling of events from multiple sources within an application process at the level of event demultiplexing. By us- Usage: The Reactor is used for the following event dis- ing the Reactor pattern, the need for more complicated patching operations in a Gateway:

6 Concrete_Svc_Handler n SOCK_Stream SOCK_Connector REGISTERED 1 OBJECTS Concrete Concrete : Output : Output Svc Handler Connector Channel Channel 4: send(msg) : Input LAYER Channel LAYER open() LEVEL LEVEL 2: recv(msg) APPLICATION : Event : Event 3: route(msg) APPLICATION APPLICATION APPLICATION Handler Handler : Event Handler SVC_HANDLER A PEER_CONNECTOR 1: handle_event() INITIALIZES Connector connect_svc_handler() PEER_STREAM activate_svc_handler() :Timer : Handle handle_event() : Signal Svc Handlern Table connect(sh, addr)

LEVEL Queue LEVEL Handlers open() A LAYER LAYER FRAMEWORK FRAMEWORK : Reactor connect_svc_handler CONNECTION CONNECTION 1: (sh, addr); OS EVENT DEMULTIPLEXING INTERFACE activate_svc_handler 2: (sh); LEVEL LEVEL KERNEL KERNEL Event Handler 1 Reactor LAYER Figure 7: Using the Reactor Pattern in the Gateway LAYER handle_event() n REACTIVE REACTIVE

 Input events ±TheReactor dispatches each incoming routing message to the Input Channel associated Figure 8: Structure and Participants in the Connector Pattern with its socket handle, at which point the message is routed to the appropriate Output Channel(s). This programming interfaces (like sockets [15] and TLI [16]). The use-case is shown in Figure 7. Connector pattern resolves the following forces that impact

 Output events ±TheReactor ensures that outgoing the active initialization of services written using these lower- routing messages are eventually delivered on ¯ow con- level interfaces: trolled Output Channels described in Section 3.4 and 3.5. 1. The need to reuse active connection establishment code for each new service ± The Connector pattern permits  Connection completion events ±TheReactor dis- patches events that indicate the completion status of key characteristics of services (such as the communi- connections that are initiated asynchronously. These cation protocol or the data format) to evolve indepen- events are used by the Connector described in Sec- dently and transparently from the mechanisms used to tion 3.2. establish the connections. Since service characteristics change more frequently than connection establishment

 Reactor Connection request events ±The also dis- mechanisms this separation of concerns reduces soft- patches events that indicate the arrival of passively ware coupling and increases code reuse. initiated connections. These events are used by the Acceptor describedinSection3.3. 2. The need to make the connection establishment code portableacross platforms that contain different network The Reactor pattern has been used in many single-threaded programming interfaces ± This is particularly important event-driven frameworks (such as the Motif, Interviews [13], for asynchronous connection establishment, which is System V STREAMS [14], the ACE object-oriented commu- hard to program portably and correctly using lower- nication framework [10], and implementations of DCE and level network programming interfaces like sockets and CORBA). In addition, it forms the foundation for most of the TLI. strategic patterns presented below. 3. The need to enable ¯exible service concurrency policies ± Once a connection is established, peer applications use 3.2 The Connector Pattern the connection to exchange data to perform some type of service (e.g., remote login, WWW HTML document Intent: The Connector pattern decouples active service ini- transfer, etc.). A service can run in a single-thread, in tialization from the tasks performed once a service is initial- multiple threads, or multiple processes, regardless of ized. how the connection was established or how the services Motivation and Forces: Connection-orientedapplications were initialized. (like a Gateway) and middleware (like CORBA or Dis- 4. The need to actively establish connections with large tributed COM) are often written using lower-level network number of peers ef®ciently ± The Connector pattern can

7 By inheriting from Event Handler (shown in Fig- con : : SOCK sh: reactor : Client ure 5), a Svc Handler can register with a Reactor and Connector Connector Svc_Handler Reactor use the Reactor pattern to handle its I/O events within the connect(sh, addr) FOREACH CONNECTION same thread of control as the Connector. Conversely, a connect_svc_handler(sh, addr) INITIATE CONNECTION Svc Handler ASYNC CONNECT connect() can use the Active Object pattern and handle

PHASE PHASE INSERT IN REACTOR register_handler(con) its I/O events within a separate thread. Section 3.5 evaluates INITIATION CONNECTION handle_events() the tradeoffs between these different patterns. START EVENT LOOP select() Parameterized types are used to decouple the Connector FOREACH EVENT DO handle_event() CONNECTION COMPLETE pattern's connection establishment strategy from the type of activate_svc_handler(sh) service and the type of connection mechanism. Develop- PHASE ACTIVATE OBJECT open() SERVICE register_handler(sh) ers supply template arguments for these types to produce INSERT IN REACTOR INITIALIZATION get_handle() Application Layer Connectors (such as the Connector EXTRACT HANDLE used by the Gateway to initialize its Input and Output handle_event() Channels DATA ARRIVES ). This enables the wholesale replacement of the

PHASE svc() SVC HANDLER and PEER CONNECTOR types, without af- SERVICE PROCESS DATA PROCESSING fecting the Connector pattern's service initialization strategy. Note that a similar degree of decoupling could be achieved via inheritance and dynamic binding by using the Abstract Figure 9: Object Interaction Diagram for the Connector Pat- Factory or Factory Method patterns described in [1]. Pa- tern rameterized types were used to implement this pattern since they improve run-time ef®ciency. In general, templates trade employ asynchrony to initiate and complete multiple compile- and link-time overhead and space overhead for im- connections in non-blocking mode. By using asyn- proved run-time performance. chrony, the Connector pattern enables applications to Collaborations: The collaborations among participants in actively establish connections with a large number of the Connector pattern are divided into three phases: peers ef®ciently over long-delay WANs. 1. Connection initiation phase ± which actively con- nects one or more Svc Handlers with their peers. Structure, Participants, and Implementation: Figure 8 Connections can be initiated synchronously or asyn- illustrates the layering structure of participants in the Con- chronously. The Connector's connect method im- nector pattern.4 The Connector is a factory that assem- plements the strategy for actively establishing connec- bles the resources necessary to connect and activate a Svc tions. Handler, which is a Proxy that exchanges messages with its Peer.TheConnector's initialization strategy can estab- 2. Service initialization phase ± which activates a Svc lish connections with Peers either synchronously or asyn- Handler by calling its open method when its con- chronously. nection completes successfully. The open method of The participants in the Connection Layer of the Connec- the Svc Handler then performs service-speci®c ini- tor pattern leverage off the Reactor pattern. For instance, tialization. the Connector's asynchronous initialization strategy es- 3. Service processing phase ± which performs the tablishes a connection after the Reactor noti®es it that a application-speci®c service processing using the data previously initiated connection request to a Peer has com- exchanged between the Svc Handler and its con- pleted. Using the Reactor pattern enables multiple Svc nected Peer. Handlers to be initialized actively within a single thread of control. Figure 9 illustrates these three phases of collaboration us- To increase ¯exibility, the implementation of a ing asynchronous connection establishment. Note how the Connector can be parameterized by a particular type connection initiation phase is temporally separated from the of PEER CONNECTOR and SVC HANDLER.ThePEER service initialization phase. This enables multiple connec- CONNECTOR supplies the underlying transport mechanism tion initiationsto proceed in parallel within a single thread of (such as C++ wrappers for sockets or TLI) used by the control. The collaborationfor synchronous connection estab- Connector to actively establish a connection. The SVC lishment is similar. In this case, the Connector combines HANDLER speci®es an abstract interface for de®ning a ser- the connection initiationand service initializationphases into vice that communicates with a connected Peer.ASvc a single blocking operation. Handler can be parameterized by a PEER STREAM end- In general, synchronous connection establishment is useful point. The Connector associates this endpoint to its Peer for the following situations: when a connection is actively established.

 If the latency for establishing a connection is very low 4In this ®gure the dashed rectangles indicate template parameters and a (e.g., establishing a connection with a server on the same dashed directed edge indicates template instantiation. host via the loopback device);

8  If multiple threads of control are available and it is feasible to use a different thread to connect each Svc : Channel: Channel : Channel Handler synchronously; : Channel : Channel : Svc : Channel

 : Svc : Svc If a client application cannot perform useful work until : Svc : Svc HandlerHandler Handler a connection is established. Handler Handler : Svc Handler In contrast, asynchronous connection establishment is useful for the following situations: : Connector ACTIVE : Channel CONNECTIONS : Svc  If the connection latency is high and there are many Handler peers to connect with (e.g., establishing a large number PENDING : Reactor of connections over a high-latency WAN); CONNECTIONS

 If only a single thread of control is available (e.g., if the OS platform does not provide application-level threads); Figure 10: Using the Connector Pattern in the Gateway

 If the client application must perform additional work (such as refreshing a GUI) while the connection is in the process of being established. connections complete, the Connector removes each con- nected Channel from its table and activates it. In the single- It is often the case that network services like the Gateway threaded implementation Input Channels register them- must be developed without knowing if they will connect selves with the Reactor once they are activated. Hence- synchronously or asynchronously. Therefore, components forth, when routing messages arrive, Input Channels provided by a general-purpose network programming frame- receive and forward them to Output Channels,which work must support multiple synchronous and asynchronous deliver the messages to their destinations (these activities are use-cases. describedinSection3.4). The Connector pattern increases the ¯exibility and reuse In addition to establishing connections, a Gateway can of networking framework components by separating the use the Connector in conjunction with the Reactor to connection establishment logic from the service process- ensure that connections are restarted if network errors occur. ing logic. The only coupling between a Connector and This enhances the Gateway's fault tolerance by ensuring a Svc Handler occurs in the service initialization phase, that channels are automatically reinitiated when they discon- when the Connector invokes the open method of the Svc nect unexpectedly (e.g., if a Peer crashes or an excessive Handler. At this point, the Svc Handler can perform amount of data is queued at an Output Channel due its service-speci®c processing using any suitable application- to network congestion). If a connection fails unexpectedly, level protocol or concurrency policy. For instance, when an exponential-backoff algorithm can be implemented using messages arrive at a Gateway,theReactor can be used the timer-based dispatching capabilities of the Reactor to to dispatch Input Channels to frame the messages, de- restart the connection ef®ciently. termine outgoing routes, and deliver the messages to their Output Channels . However, a different type of con- 3.3 The Acceptor Pattern currency mechanism (such as Active Objects described in Section 3.5) can be used by the Output Channels to Intent: The Acceptor pattern decouples passive service ini- send the data to the remote destinations. tialization from the tasks performed once the service is ini- Usage: The Connector pattern is used by the Gateway tialized. to simplify the task of connecting to a large number of Motivationand Forces: The Acceptor pattern resolves the Peers. Peer addresses are read from a con®guration ®le following forces that impact the passive initialization of ser- during Gateway initialization. The Gateway uses the vices written using lower-level network programming inter- Builder pattern [1] to bind these addresses to dynamically faces like sockets and TLI: allocated Channels.SinceChannels inherit from Svc Handler, all connections can be initiated asynchronously 1. Theneed to reusepassiveconnection establishment code using the Iterator pattern [1]. The connections are then com- for each new service ± The Acceptor pattern permits key pleted in parallel using the Connector. characteristics of services (such as the communication Figure 10 illustrates the relationship between participants protocol or the data format) to evolve independently and in the Connector pattern after four connections have been transparently from the mechanisms used to establish the established. Three other connections that have not yet connections. Since service characteristics change more completed are owned by the Connector. As shown in frequently than connection establishment mechanisms this ®gure, the Connector maintains a table of the three this separation of concerns helps reduce software cou- Channels whose connections are pending completion. As pling and increases code reuse.

9 Concrete_Svc_Handler n SOCK_Stream SOCK_Acceptor acc : : SOCK sh: reactor : 1 Server Concrete Acceptor Acceptor Svc_Handler Reactor Concrete open() Svc Handler INITIALIZE PASSIVE open() Acceptor ENDPOINT LAYER LAYER open() register_handler(acc) REGISTER HANDLER APPLICATION APPLICATION get_handle() PHASE EXTRACT HANDLE

ENDPOINT START EVENT LOOP handle_events() SVC_HANDLER INITIALIZATION select() A PEER_ACCEPTOR FOREACH EVENT DO INITIALIZES Acceptor handle_event() CONNECTION EVENT sh = make_svc_handler() PEER_STREAM CREATE, ACCEPT, accept_svc_handler (sh) make_svc_handler() activate_svc_handler (sh) Svc accept_svc_handler() AND ACTIVATE OBJECT PHASE register_handler(sh) Handler activate_svc_handler() SERVICE REGISTER HANDLER FOR CLIENT I/O get_handle() open() INITIALIZATION LAYER LAYER open() A EXTRACT HANDLE handle_event() handle_event() CONNECTION CONNECTION DATA EVENT svc() PROCESS MSG sh = make_svc_handler(); handle_close() accept_svc_handler (sh); PHASE CLIENT SHUTDOWN SERVICE activate_svc_handler (sh); handle_close() PROCESSING SERVER SHUTDOWN

Event Handler Figure 12: Object Interaction Diagram for the Acceptor Pat- 1 Reactor LAYER LAYER handle_event() n tern REACTIVE REACTIVE

difference in connection roles is illustratedby the forces these Figure 11: Structure and Participants in the Acceptor Pattern two patterns resolve. For instance, note that the ®rst three forces resolved by the Acceptor pattern are essentially the same as for the Connector pattern, with only the passive and 2. The need to make the connection establishment code active roles reversed. However, the ®nal force resolved in portable across platformsthat contain different network each pattern is different due to the inverse connection roles programming interfaces ± Parameterizing the Accep- played by each pattern. tor's mechanisms for accepting connections and per- Structure, Participants, and Implementation: Figure 11 forming services helps to improve portability by allow- illustrates the layering structure of participants in the Ac- ing the wholesale replacement of these mechanisms. ceptor pattern, which is nearly identical to the Connector This makes the connection establishment code portable layering structure in Figure 8. The Acceptor is a factory across platforms that contain different network program- that assembles the resources necessary to create, accept, and ming interfaces (such as sockets but not TLI, or vice activate a Svc Handler.TheSvc Handler in the Ac- versa). ceptor pattern plays the same role as in the Connector pattern, 3. The need to enable ¯exible service concurrency policies i.e., it is a local Proxy for a remotely connected Peer. ± Once a connection is established, peer applications use The Connection Layer in the Acceptor pattern leverages off the connection to exchange data to perform some type the Reactor pattern. For instance, the Acceptor's initial- of service (e.g., remote login, WWW HTML document ization strategy establishes a connection after the Reactor transfer, etc.). A service can run in a single-thread, noti®es it that a new connection request has arrived from in multiple threads, or multiple processes, regardless a Peer. Using the Reactor pattern enables multiple Svc regardless of how the connection was established or Handlers to be initialized passively within a single thread how the services were initialized. of control. 4. The need to ensure that a passive-mode I/O handle is To increase ¯exibility, the implementation of an not accidentallyused to read or write data ± By strongly Acceptor can be parameterized by a particular type decoupling the Acceptor from the Svc Handler, of PEER CONNECTOR and SVC HANDLER.ThePEER passive-mode listener endpoints cannot be used incor- ACCEPTOR supplies the underlying transport mechanism rectly (e.g., to try to read or write data on a passive- (such as C++ wrappers for sockets or TLI) used by the mode listener socket used to accept connections). This Acceptor to passively establish a connection. The SVC eliminates an important class of network programming HANDLER speci®es an abstract interface for de®ning a ser- errors. vice that communicates with a connected Peer.ASVC HANDLER can be parameterized by a PEER STREAM end- The Acceptor pattern is the ªdualº of the Connector pattern point. The Acceptor associates this endpoint to its Peer described in Section 3.2. However, the Connector pattern es- when a connection is established passively. tablishes connections actively, whereas the Acceptor pattern As with the Connector pattern, a Svc Handler can use establishes connections passively. The consequences of this either the Reactor pattern or Active Object pattern to handle

10 Routing Table Message 1 Queue : Input : Output find() Channel Channel n : Output Input Output LAYER : Svc : Svc Channel LAYER ROUTING ROUTING Channel Channel Handler Handler : Input recv_msg() send_msg() Acceptor : Svc Handler put()

ACTIVE PASSIVE CONNECTIONS : Output LISTENERS : Input Acceptor Channel EVENT SOURCE AND SINK I/O I/O LAYER LAYER : Reactor : Svc Handler Figure 14: Structure and Participants in the Router Pattern

Figure 13: Using the Acceptor Pattern in the Gateway Usage: Figure 13 illustrates how the Acceptor pattern is used by the Gateway.TheGateway uses this pattern when it plays the passive connection role. In this case, its I/O events. Likewise, the implementation of the Accep- Peers connect to Gateway, which uses the Acceptor pat- tor pattern presented above also uses parameterized types. tern to decouple the passive initialization of Input and Parameterized types enhance portability since the Acceptor Output Channels from the routing tasks performed once pattern's connection establishment strategy is independent of a Channel is initialized. the type of service and the type of IPC mechanism. De- The intent and general architecture of the Acceptor pattern velopers can supply concrete arguments for these types to is found in network server management tools likeinetd [15] produce Application Layer Concrete Acceptor (such and listen [16]. These tools utilize a master Acceptor pro- as the Acceptor used by the Gateway and Peers to cess that listens for connections on a set of communication passively initialize Input and Output Channels). ports. Each port is associated with a communication-related service (such as the standard Internet services ftp, telnet, Collaboration: Figure 12 illustrates the collaboration daytime,andecho). When a service request arrives on among participants in the Acceptor pattern. These collab- a monitored port, the Acceptor process accepts the request orations are divided into three phases: and dispatches an appropriate pre-registered handler that per- forms the service. 1. Endpoint initialization phase ± which creates a passive- mode endpoint (encapsulated by PEER ACCEPTOR) that is bound to a network address (such as an IP address 3.4 The Router Pattern and port number). The passive-mode endpoint listens for connection requests from Peers. This endpoint is Intent: The Router pattern decouples multiple sources of registered with the Reactor, which drives the event input from multiple sources of output to route data correctly Gateway loop that waits on the endpoint for connection requests without blocking a . to arrive from Peers. Motivation and Forces: Message routing in a Gateway must not be disrupted or postponed inde®nitely when con- 2. Service activation phase ± Since an Acceptor in- gestion or failure occurs on incoming and outgoing network herits from an Event Handler the Reactor can links. The Router pattern resolves the following forces that dispatch the Acceptor's handle event method arise when building robust connection-oriented Gateways: when connection events arrive. This method performs Acceptor Svc Handler the 's initialization strat- 1. The need to prevent misbehaving connections from dis- egy. This strategy assembles the resources necessary to rupting the quality of service for well-behaved connec- create a new Concrete Svc Handler object, ac- tions ± If outgoing connections can ¯ow control as a cept the connection into this object, and activate the Svc result of network congestion, or input connections can Handler open by calling its method. fail because Peers disconnect, the Gateway must not 3. Service processing phase ± once activated, the Svc perform blocking send or recv operations on any sin- Handler processes incoming event messages arriving gle channel. Otherwise, messages on other channels on the PEER STREAM.ASvc Handler will process could not be sent or received and the quality of service incoming event messages using a concurrent event han- provided to Peers would degrade. dling pattern such as the Reactor or the Active Object 2. The need to allow different concurrency strategies [9]. for Input and Output Channels ± Several concur-

11 rency strategies for processing Input and Output Channels are described in this paper including (1) single-threaded processing using the Reactor pattern : Routing : Output : Input I/O main() and (2) multi-threaded processing using the Active Ob- Table Channel Channel Layer

ject pattern. Each strategy is appropriate under differ- INPUT recv_msg() PHASE RECV MSG

ent situations, depending on factors such as the num- PROCESSING ROUTE MSG ber of CPUs, context switching overhead, and number find () of Peers. By decoupling Input Channels from FIND DESTINATIONS put() Output Channels the Router pattern allows cus- SEND MSG (QUEUE IF FLOW send_msg() PHASE enqueue() tomized concurrency strategies to be con®gured ¯exibly ROUTE CONTROLLED) into a Gateway. SELECTION schedule_wakeup() wakeup() FLOW CONTROL ABATES Structure, Participants, and Implementation: Figure 14 dequeue() DEQUEUE AND SEND illustrates the layer structuring of participants in the Router PHASE MSG (REQUEUE IF send_msg() OUTPUT FLOW CONTROLLED) pattern. The I/O Layer provides an event source for Input PROCESSING Channels and an event sink for Output Channels. An Input Channel uses a Routing Table to map Figure 15: Object Interaction Diagram for the Router Pattern routing messages onto one or more Output Channels. If messages cannot be delivered to their destination Peers immediatelytheyarebufferedinaMessage Queue for Active Object version of the Router pattern). The Router pat- subsequent transmission. tern uses a Reactor as a cooperative multi-tasking sched- Because Input Channels are decoupled from uler for Gateway I/O operations, just like the Connector and Output Channels their implementations can vary inde- Acceptor patterns. The Reactor allows multiple events on pendently. This separation of concerns is important since it different connections to be demultiplexed within a single allows different concurrency strategies to be used for input thread of control. The use of single-threading eliminates and output. The consequences of this decouplingis discussed the overhead of synchronization (since access to shared ob- further in Section 3.5. jects like the Routing Table need not be serialized) and context switching (since message routing occurs in a single Collaborations: Figure 15 illustrates the collaboration thread). among participants in the Router pattern. These collabo- In the Reactor version of the Router pattern, the Input rations can be divided into three phases: Channels and Output Channels inherit indirectly from Event Handler. This enables the Gateway 1. Input processing phase±whereInput Channels re- to route messages by having the Reactor dispatch assemble incoming TCP segments into complete routing the handle event methods of Input and Output messages; Channels when messages arrive and ¯ow control condi- 2. Route selection phase ±whereInput Channels tions subside, respectively. consult a Routing Table to select the Output Using the Reactor pattern to implement the Router pattern Channels responsible for sending the routing mes- involves the following steps: sages; 1. Initialize non-blocking endpoints ±TheInput and 3. Output processing phase ± where the selected Output Output Channel handles are set into non-blocking Channels transmit the routing messages to their des- mode after they are activated by an Acceptor or tination(s) without blocking the process. Connector. The use of non-blocking I/O is essen- tial to avoid subtle errors that can occur on faulty or Usage: The other strategic patterns in this paper (i.e., Reac- congested network links. tor, Connector, Acceptor, and Active Object) can be applied to many other types of communication software. In con- 2. Input message reassembly and routing ± Routing mes- trast, the Router pattern is tightly coupled with the Gateway sages are received in fragments by Input Channels. application. A primary challenge of building a reliable If an entire message is not immediately available, the connection-oriented Gateway centers on avoiding block- Input Channel must buffer the fragment and return ing I/O. This is necessary to reliably manage ¯ow control control to the event loop. This is essential to prevent on Output Channels.IftheGateway blocked inde®- ªhead of lineº blocking on Input channels.When nitely when sending on acongested connection then incoming an Input Channel successfully receives and frames messages could not be routed, even if those messages were an entire message it uses the Routing Table to de- destined for non-¯ow controlled Output Channels. termine the appropriate set of Output Channels The remainder of this section describes how the Router pat- that will deliver the message. tern can be implemented in a single-threaded, Reactor version 3. Message delivery ± The selected Output Channels of the Gateway (Section 3.5 examines the multi-threaded, try to send the message to the destination Peer.Mes-

12 : Output loop { Client m = actQueue.remove() : Routing Channel Interface dispatch (m) Table } : Message 5: nonblk_put(msg) ResultHandle m1() Queue 6: send_msg(msg) ResultHandle m2() Scheduler ROUTE ResultHandle m3() ID dispatch() Subscriber m1'() Activation Set : Output 3: find() m2'() 1 Queue Channel VISIBLE m3'() 1 insert() TO remove() : Message CLIENTS 1 4: put (msg) Queue 1

7: put (msg) 8: nonblk_put(msg) 1 n : Input 9: send_msg(msg) INVISIBLE Channel 10: enqueue(msg) TO Resource Method 11: schedule_wakeup() CLIENTS ------Representation Objects 1: handle_event() 12: wakeup() 2: recv_msg(msg) 13: dequeue(msg) 14: send_msg(msg)

Figure 17: Structure and Participants in the Active Object Figure 16: Using the Router Pattern in a Single-threaded Pattern Reactive Gateway Motivation and Forces: All the strategic patterns used by the single-threaded Gateway in Section 3.4 are layered upon sages must be delivered reliably in ª®rst-in, ®rst-outº the Reactor pattern. The Connector, Acceptor, and Router (FIFO) order. To avoid blocking, all send operations patterns all use the Reactor as a scheduler/dispatcher to ini- in Output Channels must check to make sure that tialize and route messages within a single thread of control. the network link is not ¯ow controlled. If it is not,the In general, the Reactor pattern forms the central event loop in message can be sent successfully. This path is depicted single-threaded reactive systems. For example, in the single- by the Output Channel in the upper right-hand cor- threaded Gateway implementation, the Reactor provides ner of Figure 16. If the link is ¯ow controlled, however, a coarse-grained form of concurrency control that serializes the Router pattern must use a different strategy. This the invocation of event handlers at the level of event demul- path is depicted by the Output Channel in the lower tiplexing and dispatching within a process. This eliminates right-hand corner of Figure 16. the need for additional synchronization mechanisms within a To handle ¯ow controlled connections, the Output Gateway and minimizes context switching. Channel inserts the message it is trying to send into The Reactor pattern is well-suited for applications that use its Message Queue. It then instructs the Reactor short-duration callbacks (such as passive connection estab- to call back to the Output Channel when the ¯ow lishment in the Acceptor pattern). It is less appropriate, how- control conditions abate, and returns to the main event ever, for long-duration operations (such as blocking on ¯ow loop. When it is possible to try to send again, the controlled Output Channels during periods of network Reactor dispatches the handle event method on congestion). In fact, much of the complexity in the single- the Output Channel, which then retries the opera- threaded Router pattern implementation stems from using the tion. This sequence of steps may be repeated multiple Reactor pattern as a cooperative multi-tasking mechanism. It times until the entire message is transmitted success- is much easier, therefore, to implement the output portion of fully. the Router pattern with the Active Object pattern. This pattern allows Output Channels to block independently when sending messages to Peers. Note that the Gateway always returns control to its main The Active Object pattern resolves the followingforce that event loop immediately after every I/O operation, regardless impacts the design of applications like a Gateway that must of whether it sent or received an entire message. This is communicate simultaneously with multiple Peers: the essence of the Router pattern ± it correctly routes the messages to peers without blocking on any singleI/O channel.

 The need to allow blocking read and write operations on one endpoint that do not detract from the quality of 3.5 The Active Object Pattern service of other endpoints. Network services are gener- ally easier to program if blocking I/O is used rather than reactive non-blocking I/O [17]. The increased simplic- Intent: The Active Object pattern decouples method exe- ity occurs since the execution state can be localized in cution from method invocation to enable concurrent execu- the activation records of a thread of control, rather than tion of methods. being decentralized in a set of control blocks maintained

13 : Client : Activation : Represent- client : Scheduler Interface Queue ation : Routing : Output m1() Table Channel INVOKE 5: send_msg(msg) CREATE METHOD cons(m1') OBJECT : Message Queue RETURN RESULT future() CONSTRUCTION METHOD OBJECT HANDLE METHOD OBJECT ROUTE ACTIVE

/ ID Subscriber INSERT IN insert(m1') PRIORITY QUEUE 3: find() Set DEQUEUE NEXT remove(m1') 4: put (msg) METHOD OBJECT : Output EXECUTION Channel

EXECUTE dispatch(m1') : Input : Message RETURN RESULT reply_to_future() Channel Queue

COMPLETION ACTIVE 1: handle_event () 5: send_msg(msg) 2: recv_msg(msg) Figure 18: Object Interaction Diagram for the Active Object Pattern Figure 19: Using the Router Pattern in a Multi-threaded Active Object Gateway by application developers. passes return values back to the caller when the method Structure, Participants, and Implementation: Figure 17 ®nishes executing. A future is a synchronization object illustrates the structure and participants in the Active Ob- that enforces ªwrite-once, read-manyº synchronization. ject pattern. The Client Interface presents the pub- Subsequently, any readers that rendezvous with the fu- lic methods available to clients. The Scheduler deter- ture will evaluate the future and obtain the result value. mines next method to execute based on synchronization The future and the Method Object will be garbage and scheduling constraints. The Activation Queue collected when they are no longer needed. maintains a list of pending Method Objects.The Scheduler determines the order in which these Methods Usage: The Gateway implementation described in Sec- Objects are executed (a FIFO scheduler is used in the tion 3.4 is single-threaded. It uses the Reactor pattern imple- Gateway to maintain the order of message delivery). The mentation of theRouter Pattern as acooperativemulti-tasking Resource Representation maintains context infor- scheduler that dispatches events of interest to a Gateway. mation shared by the implementation methods. After implementing a number of single-threaded Gateways Collaborations: Figure 18 illustrates the collaborations it became clear that using the Reactor pattern as the basis for among participants in the Active Object pattern. These col- all Gateway routing I/O operations was error-prone and laborations are divided into the following phases: hard to maintain. For example, maintenance programmers frequently did not recognize the importance of returning con- 1. Method Object construction ± in this phase the client trol to the Reactor's event loop immediately when I/O op- application invokes a method de®ned by the Client erations cannot proceed. This misunderstanding became a Interface. This triggers the creation of a Method common source of errors in single-threaded Gateways. Object, which maintains the argument bindings to To avoid these problems, a number of multi-threaded the method, as well as any other bindings required to Gateways were built using variations of the Active Ob- execute the method and return a result. For example, a ject pattern. The remainder of this section describes how binding to a Result Handle object returned to the Output Channels can be multi-threading using the Ac- caller of the method. A Result Handle is returned tive Object pattern.5 This modi®cation greatly simpli®ed to the client unless the method is ªoneway,º in which the implementation of the Router pattern since Output case no Result Handle is returned. Channels can block in their own thread of control with- 2. Scheduling/execution ± in this phase the Scheduler out affecting other Channels. Implementing the Output acquires a mutual exclusion , consults the Channels as Active Objects also eliminated the sub- Activation Queue to determine which Method tle and error-prone cooperative multi-tasking programming Object(s) meet the synchronization constraints. techniques required when using the Reactor to schedule The Method Object is then bound to the current Output Channels. Resource Representation and the method is al- Figure 19 illustrates the Active Object version of the lowed to access/update this representation and create a Router pattern. Note how much simpler is it compared with Result Handle. 5While it is possible to apply the Active Object pattern to the Input 3. Return result ± the ®nal phase binds the Result Channels this has less impact on the Gateway design because the Handle value, if any, to a future [18, 19] object that Reactor already supports non-blocking input.

14 the Reactor solution in Figure 16. The simpli®cation occurs used to create the task. The Connector pattern is a Factory primarily since the complex output scheduling logic moved that use Template Methods to create, connect, and activate into the Active Objects, rather than being the responsibility handlers for communication channels. In the Connector pat- of the application programmer. tern, the connect method implements a standard algorithm It is also possible to observe the difference in complexity for initiating a connection and activating a handler when the between the single-threaded and multi-threaded Gateways connection is established. The intentof the Connector pattern by examining the source code that implements the Router is similar to the Client/Dispatcher/Server pattern described in pattern in production Gateway systems. 6 However, using [5]. They both are concerned with separating active connec- source code to identify the reasons behind this complexity tion establishment from the subsequent service. The primary is hard due to all the error handling and protocol-speci®c difference is that the Connector pattern addresses both syn- details that surround the implementation. These details tend chronous and asynchronous connection establishment. to disguise the key insight: the main difference between the The Acceptor pattern can also be viewed as a variation of complexity of the single-threaded and multi-threaded solu- the Strategy and Factory Method patterns [1]. The Acceptor tions arise from the choice of the Reactor pattern vs. the pattern is a connection factory that embodies the strategy for Active Object pattern. This paper has explicitly focused on create service handlers, accepting connections into service the interactions and tradeoffs between these patterns in or- handlers, and activating service handles to process data ex- der to clarify the consequences of different design choices. changed across communication channels. The Acceptor In general, documenting the interactions and relationships implements the algorithm that passively listens for connec- between closely related patterns is a very challenging and tion requests, then creates and activates a handler when the unresolved topic that is currented be addressed by the pat- connection is established. The handler performs a service terns community. using data exchanged on the connection. Thus, the service is decoupled from the network programming interface and the transport protocol used to establish the connection. 4 Related Work The Router pattern is a variant of the [1], which decouples cooperating components of a software sys- [1, 5, 20] identify, name, and catalog many fundamental tem and allows them to interact without having direct depen- object-oriented design patterns. This section examines how dencies among each other. The Router pattern is specialized the patterns described in this paper relate to other patterns in to resolve the forces associated with network communication. the literature. Note that many of the tactical patterns form It decouples the mechanisms used to process input messages the basis for implementing the strategic patterns presented in from the mechanisms used to process output mechanisms to this paper. prevent blocking. In addition, the Router pattern allows the The Reactor pattern is related to the [1]. use of different concurrency strategies for input and output In the Observer pattern, multiple dependents are updated au- channels. tomatically when a subject changes. In the Reactor pattern, a handler is dispatched automatically when an event occurs. Thus, the Reactor dispatches a single handler for each event 5 Concluding Remarks (though there can be multiple sources of events). The Reac- tor pattern also provides a Facade [1]. The This paper illustrates how a family of patterns have been presents an interface that shields applications from complex applied to facilitate widespread reuse of design exper- relationshipswithin a subsystem. The Reactor pattern shields tise and software components in production communication applications from complex mechanisms that perform event Gateways. These patterns illustrate the structure of, and demultiplexing and event handler dispatching. collaboration between, objects that perform core communi- The mechanism the Reactor uses to dispatch Event cation software tasks. The tasks addressed by these patterns Handlers is similar to the Factory Callback pattern [21]. include event demultiplexing and event handler dispatching, The intent of both patterns is to decoupling event reception connection establishment and initialization of application ser- from event processing. The primary different is the purpose vices, concurrency control, and routing. of the pattern ± the Factory Callback is a , The family of design patterns and the ACE framework whereas the Reactor dispatching is a . components described in this paper have been reused by the The Connector pattern is a variation of the Template author and his colleagues in many production communica- Method and Factory Method patterns [1]. In the Template tion software systems ranging from telecommunication and Method pattern, an algorithm is written such that some steps electronic medical imaging projects [12, 3] to academic re- are supplied by a derived class. In the Factory Method pat- search projects [10]. In general, patterns aid the development tern, a method in a subclass creates an associate that performs of components and frameworks in these systems by capturing a particular task, but the task is decoupled from the protocol the structure and collaboration of participants in a software architecture at a higher level than (1) source code and (2) 6An ACE-based example of single-threaded and multi-threaded Gateways that illustrates all the patterns in this paper is freely available object-oriented design models that focus on individual ob-

via the WWW at http://www.cs.wustl.edu/schmidt. jects and classes.

15 Our experience applying a design pattern-based reuse strat- 6th USENIX C++ Technical Conference, (Cambridge, Mas- egy has been quite positive [2]. For instance, we've signi®- sachusetts), USENIX Association, April 1994. cantly reduced the software maintenance and training effort [11] D. C. Schmidt, T. H. Harrison, and E. Al-Shaer, ªObject- for the production communication systems by documenting Oriented Components for High-speed Network Program- the intent, structure, and behavior of ACE components in ming,º in Proceedings of the 1st Conference on Object- terms of the patterns they reify. Focusing on patterns has Oriented Technologies and Systems, (Monterey, CA), USENIX, June 1995. also enabled us to reuse software architecture even when reuse of algorithms, implementations, interfaces, or detailed [12] D. C. Schmidt and P. Stephenson, ªExperiences Using De- sign Patterns to Evolve System Software Across Diverse OS designs was not feasible due to differences in OS platforms Platforms,º in Proceedings of the 9th European Conference [12]. An in-depth discussion of our experiences and lessons on Object-Oriented Programming,(Aarhus, Denmark), ACM, learned using patterns appeared in [2]. August 1995. [13] M. A. Linton, J. Vlissides, and P. Calder, ªComposing User Interfaces with InterViews,º IEEE Computer, vol. 22, pp. 8± Acknowledgements 22, February 1989. [14] D. Ritchie, ªA Stream Input±OutputSystem,º AT&T Bell Labs I would like to thank Steve Berczuk, Chris Cleeland, Tim Technical Journal, vol. 63, pp. 311±324, Oct. 1984. Harrison, Hans Rohnert, and the anonymous referees for [15] W. R. Stevens, UNIX Network Programming, First Edition. contributing valuable suggestions that helped improve the Englewood Cliffs, NJ: Prentice Hall, 1990. quality of this paper. [16] S. Rago, UNIX System V Network Programming. Reading, MA: Addison-Wesley, 1993. References [17] D. C. Schmidt and C. D. Cranor, ªHalf-Sync/Half-Async: an for Ef®cient and Well-structured Con- [1] E. Gamma, R. Helm, R. Johnson, and J. Vlissides, Design current I/O,º in Pattern Languages of Program Design (J. O. Patterns: Elements of Reusable Object-Oriented Software. Coplien, J. Vlissides, and N. Kerth, eds.), Reading, MA: Reading, MA: Addison-Wesley, 1995. Addison-Wesley, 1996. [2] D. C. Schmidt, ªExperience Using Design Patterns to Develop [18] R. H. Halstead, Jr., ªMultilisp: A Language for Concur- Reuseable Object-Oriented Communication Software,º Com- rent Symbolic Computation,º ACM Trans.ProgrammingLan- munications of the ACM (Special Issue on Object-Oriented guages and Systems, vol. 7, pp. 501±538, Oct. 1985. Experiences), vol. 38, October 1995. [19] B. Liskov and L. Shrira, ªPromises: Linguistic Support for Ef®cient Asynchronous Procedure Calls in Distributed Sys- [3] I. Pyarali, T. H. Harrison, and D. C. Schmidt, ªDesign and tems,º in Proceedingsof the SIGPLAN'88 Conferenceon Pro- Performance of an Object-Oriented Framework for High- gramming Language Design and Implementation, pp. 260± Performance Electronic Medical Imaging,º in Proceedings

nd 267, June 1988. of the 2 Conference on Object-Oriented Technologies and Systems, (Toronto, Canada), USENIX, June 1996. [20] J. O. Coplien and D. C. Schmidt, eds., Pattern Languages of Program Design. Reading, MA: Addison-Wesley, 1995. [4] D. C. Schmidt and T. Suda, ªMeasuring the Performance of Parallel Message-based Process Architectures,º in Proceed- [21] S. Berczuk, ªA Pattern for Separating Assembly and Process- ings of the Conference on Computer Communications (INFO- ing,º in Pattern Languages of Program Design (J. O. Coplien COM), (Boston, MA), pp. 624±633, IEEE, April 1995. and D. C. Schmidt, eds.), Reading, MA: Addison-Wesley, 1995. [5] F. Buschmann, R. Meunier, H. Rohnert, P. Sommerlad, and M. Stal, Pattern-Oriented Software Architecture - A System of Patterns. Wiley and Sons, 1996. [6] G. Booch, Object Oriented Analysis and Design with Ap- plications (2 nd Edition). Redwood City, California: Ben- jamin/Cummings, 1993. [7] D. C. Schmidt, ªReactor: An Object Behavioral Pattern for Concurrent Event Demultiplexing and Event Handler Dis- patching,º in Pattern Languages of Program Design (J. O. Coplien and D. C. Schmidt, eds.), Reading, MA: Addison- Wesley, 1995. [8] D. C. Schmidt, ªAcceptor and Connector: Design Patterns for Initializing Communication Services,º in The 1st European Pattern Languages of Programming Conference (Washington University technical report #WUCS-97-07), July 1997. [9] R. G. Lavender and D. C. Schmidt, ªActive Object: an Object Behavioral Pattern for Concurrent Programming,º in Proceed- ings of the 2nd Annual Conference on the Pattern Languages of Programs, (Monticello, Illinois), pp. 1±7, September 1995. [10] D. C. Schmidt, ªACE: an Object-Oriented Framework for Developing Distributed Applications,º in Proceedings of the

16