Motivation

Design Patterns and Frameworks

for Object-oriente d

 Developing ecient, robust, extensible, and

Communicatio n Systems

reusable communication software is hard

 It is essential to understand successful tech-

Douglas C. Schmidt

niques that have proven e ective to solve

common development challenges

http://www.cs.wustl.ed u/s chmi dt/

 and frameworks help to cap-

[email protected] u

ture, articulate, and instantiate these suc-

cessful techniques

Washington University, St. Louis

1 2

Observations

Design Patterns

 Develop ers of communication software con-

 Design patterns represent solutions to prob-

front recurring challenges that are largely

lems that arise when developing software

application-indep endent

within a particular context

{ e.g., service initialization and distribution, error

{ i.e.,\Patterns == problem/solution pairs in a con-

handling, ow control, event demultiplexing, con-

text"

currency control

 Patterns capture the static and dynamic struc-

 Successful develop ers resolve these challenges

ture and collab oration among key partici-

pants in software designs

by applying appropriate design patterns

{ They are particularly useful for articulating how

and why to resolve non-functional forces

 However, these patterns have traditionally

b een either:

1. Lo cked inside heads of exp ert develop ers

 Patterns facilitate reuse of successful soft-

ware architectures and designs

2. Buried in source co de

4 3

Proxy Pattern

Graphical Notation

1: METHOD : BROKER CALL

: QUOTER 4: METHOD OBJECT PROXY RETURN PROCESS : CLASS

2: FORWARD REQUEST

3: RESPONSE

CLASS CLIENT CLASS TEMPLATE UTILITY : QUOTER CLASS NETWORK

CLASS CATEGORY INHERITS INSTANTIATES SERVER

ABSTRACT CLASS

A CONTAINS USES

 Intent: provide a surrogate for another ob-

ject that controls access to it

5 6

Frameworks

 A framework is:

More Observations

{ \An integrated collection of comp onents that col-

lab orate to pro duce a reusable architecture for a

 Reuse of patterns alone is not sucient

family of related applications"

{ Patterns enable reuse of architecture and design

knowledge, but not co de directly

 Frameworks di er from conventional class

libraries:

1. Frameworks are \semi-complete" applications

 Tobepro ductive, develop ers must also reuse

detailed designs, algorithms, interfaces, im-

2. Frameworks address a particular application do-

main

plementations, etc.

3. Frameworks provide \"

 Application frameworks are an e ective way

to achieve broad reuse of software

 Typically, applications are develop ed by in-

heriting from and instantiating framework

comp onents

7 8

Di erences Between Class

Libraries and Frameworks

Tutorial Outline

APPLICATION NETWORKING SPECIFIC LOGIC

INVOKES MATH ADTS

 Outline key challenges for developing com-

software EVENT USER munication DATA LOOP INTERFACE

BASE

Present the key reusable design patterns in

CLASS 

distributed medical imaging system

LIBRARIES a

{ Both single-threaded and multi-threaded solutions

are presented NETWORKING MATH USER INTERFACE APPLICATION CALL

INVOKES SPECIFIC

Discuss lessons learned from using patterns BACKS  LOGIC EVENT

LOOP

on pro duction software systems ADTS DATABASE

OBJECT-ORIENTED

FRAMEWORK

9 10

Concurrency vs. Parallelism

Stand-alone vs. Distribut ed

Application Architectures SERVER

PRINTER maxfdp1 read_fds COMPUTER CLIENT WORK REQUEST FILE CD ROM SYSTEM WORK WORK WORK CLIENT REQUEST REQUEST REQUEST (1) STAND-ALONE APPLICATION ARCHITECTURE

CLIENT CLIENT

DISPLAY CYCLE CONCURRENT SERVER SERVICE SERVICES

FI LE SERVER SERVICE CPU1 CPU2 CPU3 CPU4 PRINT NETWORK SERVICE CLIENT

WORK REQUEST PRINTER CD ROM FILE SYSTEM WORK WORK WORK CLIENT REQUEST REQUEST REQUEST (2) DISTRIBUTED APPLICATION ARCHITECTURE

CLIENT CLIENT

PARALLEL SERVER

11 12

Sources of Complexity

Sources of Complexity cont'd

 Distributed application development exhibits

b oth inherent and accidental complexity

 Accidental complexity results from limi ta-

tions with to ols and techniques, e.g.,

 Inherent complexity results from fundamen-

tal challenges, e.g.,

{ Low-level to ols

{ Distributed systems

. e.g., Lack of typ e-secure, portable, re-entrant,

and extensible system call interfaces and com-

. Latency

p onent libraries

. Error handling

{ Inadequate debugging supp ort

. Service partitioning and load balancing

{ Widespread use of algorithmic decomp osition

{ Concurrent systems

. Fine for explaining network programming con-

cepts and algorithms but inadequate for devel-

. Race conditions

oping large-scale distributed applications

. Deadlo ck avoidance

{ Continuous rediscovery and reinvention of core con-

cepts and comp onents

. Fair

. Performance optimization and tuning

13 14

OO Contributio ns

 Concurrent and distributed programming has

Distributed Medical Imaging

traditionally b een p erformed using low-level

OS mechanisms, e.g.,

Example

{ fork/exec

{ Shared memory

 This example illustrates the reusable design

{ Signals

patterns and framework comp onents used in

an OO architecture foradistributed medical

{ So ckets and select

imaging system

{ POSIX pthreads, Solaris threads, Win32 threads

 Application clients uses Blob Servers to store

 OO design patterns and frameworks elevate

development to fo cus on application con-

and retrieve medical images

cerns, e.g.,

{ Service functionality and p olicies

 Clients and Servers communicate via a connection-

oriented transp ort proto col

{ Service con guration

{ e.g., TCP/IP, IPX/SPX, TP4

{ Concurrent event demultiplexing and event han-

dler dispatching

{ Service concurrency and synchronization

16 15

Distributed Electronic Medical

Architecture of the Blob Server

Imaging Architecture

BLOB SERVER MODALITIES LOCAL (CT, MR, CR) STORE svc_run svc_run svc_run svc_run

ATM LAN

DIAGNOSTIC STATIONS : Blob : Msg NAME Queue : Options SERVER Processor

ATM ATM : Blob : Blob : Blob LAN MAN ROUTING Handler Handler Handler SERVICE : Blob Acceptor : Reactor CLUSTER TIME STORE SERVER

LOCATIONLOCATION SERVICESERVICE CENTRAL STORE MODALITIES

(CT, MR, CR)

* Manage short-term and long-term blob p ersistence

* Resp ond to queries from Blob Lo cators

17 18

Tactical Patterns

Design Patterns in the Blob

Server

 Proxy

{ \Provide a surrogate or placeholder for another

Thread-per object to control access to it" Thread-per Session Request

Acceptor Strategy 

Thread

\De ne a family of algorithms, encapsulate each

Pool Connector {

one, and make them interchangeable"

Half-Sync/ Service

Half-Async Adapter

Configurator  \Convert the interface of a class into another in- STRATEGIC Double Checked { Reactor terface client exp ects" PATTERNS Locking

TACTICAL Singleton

PATTERNS Proxy Strategy Adapter Singleton 

{ \Ensure a class only has one instance and provide

a global p oint of access to it"

20 19

Concurrency Patterns

 Reactor

Concurrency Architecture

{ \Decouples event demultiplexing and event han-

dler dispatching from application services p erformed

Patterns

in resp onse to events"

 Thread-p er-Request

 Active Object

{ \Allows each client request to run concurrently"

{ \Decouples metho d execution from metho d invo-

cation and simpli es synchronized access to shared

resources by concurrent threads"

 Thread-Pool

 Half-Sync/Half-Async

{ \Allows up to N requests to execute concurrently"

{ \Decouples synchronous I/O from asynchronous

I/O in a system to simplify concurrent program-

ming e ort without degrading execution eciency"

 Thread-p er-Session

{ \Allows each client session to run concurrently"

 Double-Checked Lo cking Pattern

{ \Ensures atomic initialization of objects and elim-

inates unnecessary lo cking overhead on each ac-

cess"

22 21

Concurrency Patterns in the Blob

Service Initializati on Patterns

Server

 Connector

{ \Decouples active connection establishment from

 The following example illustrates the design

the service p erformed once the connection is es-

patterns and framework comp onents in an

tablished"

OO implementation of a concurrent Blob

Server

 Acceptor

 There are various architectural patterns for

{ \Decouples passive connection establishment from

structuring concurrency in a Blob Server

the service p erformed once the connection is es-

tablished"

1. Reactive

2. Thread-p er-request

 Service Con gurator

3. Thread-p er-session

{ \Decouples the b ehavior of network services from

p oint in time at which services are con gured into

an application"

4. Thread-p o ol

24 23

Thread-p er-Req ues t Blob Server

Reactive Blob Server Architecture Architecture

2: HANDLE INPUT BLOB SERVER 3: CREATE PROCESSOR BLOB SERVER 2: HANDLE INPUT 4: ACCEPT CONNECTION 3: CREATE PROCESSOR : Blob 5: ACTIVATE PROCESSOR : Blob 4: ACCEPT CONNECTION Processor Processor 5: SPAWN THREAD : Blob : Blob Acceptor Processor : Blob : Blob Acceptor : Blob Processor Processor : Reactor : Reactor

6: PROCESS BLOB REQUEST 6: PROCESS BLOB REQUEST SERVER 1: CONNECT 1: CONNECT SERVER

CLIENT CLIENT CLIENT CLIENT

CLIENT CLIENT

25 26

Thread-Pool Blob Server

Thread-p er-Sess ion Blob Server

Architecture Architecture

BLOB SERVER : Msg 2: HANDLE INPUT BLOB SERVER : Blob Queue 2: CREATE, ACCEPT, Processor 3: ENQUEUE REQUEST AND ACTIVATE 3: SPAWN THREAD worker BLOB_PROCESSOR : Blob thread : Blob : Blob Handler : Blob : Blob : Blob 5: DEQUEUE & Handler Processor Processor : Blob Processor Acceptor worker PROCESS Handler thread REQUEST : Blob : Reactor Acceptor worker worker thread thread : Reactor

4: PROCESS BLOB REQUEST

6: PROCESS BLOB REQUEST 1: BIND SERVER CLIENT 1: BLOB REQUEST SERVER CLIENT CLIENT CLIENT CLIENT

CLIENT

27 28

The ADAPTIVE Communication

The Reactor Pattern

Environment ACE

 Intent

DISTRIBUTED GATEWAY TOKEN LOGGING NAME TIME

SERVICES SERVER SERVER SERVER SERVER SERVER

{ \Decouples event demultiplexing and event han-

dler dispatching from the services p erformed in re-

FRAMEWORKS SERVICE CORBA

ACCEPTOR CONNECTOR sp onse to events" AND CLASS HANDLER HANDLER CATEGORIES ADAPTIVE SERVICE EXECUTIVE (ASX)

C++ THREAD LOG SERVICE SHARED MANAGER MSG CONFIG- MALLOC WRAPPERS

REACTOR URATOR

This pattern resolves the following forces SYNCH SPIPE SOCK_SAP/ FIFO MEM SYSV 

WRAPPERS SAP TLI_SAP SAP MAP WRAPPERS

for event-driven software:

OS ADAPTATION LAYER

C THREAD STREAM SOCKETS/ NAMED SELECT/ DYNAMIC MEMORY SYSTEM

APIS How to demultiplex multiple typ es of events from LIBRARY PIPES TLI PIPES POLL LINKING MAPPING V IPC {

PROCESS/THREAD COMMUNICATION VIRTUAL MEMORY multiple sources of events eciently within a single

SUBSYSTEM SUBSYSTEM SUBSYSTEM thread of control

GENERAL UNIX AND WIN32 SERVICES

{ How to extend application b ehavior without requir-

 A set of C++ wrapp ers and frameworks

ing changes to the event dispatching framework

based on common design patterns

29 30

Collab oration in the Reactor

Structure of the Reactor Pattern

Pattern

select (handles); foreach h in handles { Concrete callback : if (h is output handler) Event_Handler main Concrete reactor table[h]->handle_output () ; if (h is input handler) program Event_Handler : Reactor table[h]->handle_input (); APPLICATION if (h is signal handler) Reactor() table[h]->handle_signal (); Event_Handler DEPENDENT INITIALIZE } - this->expire_timers (); handle_input() register_handler(callback) APPLICATION REGISTER HANDLER handle_output() INDEPENDENT handle_signal() - get_handle() handle_timeout() EXTRACT HANDLE MODE n get_handle() n handle_events() A START EVENT LOOP 1 1 1 INITIALIZATION select() FOREACH EVENT DO Reactor 1 Timer_Queue handle_input() handle_events() 1 n schedule_timer(h) DATA ARRIVES register_handler(h) Handles cancel_timer(h) remove_handler(h) handle_output() expire_timer(h) OK TO SEND expire_timers() n 1 1 handle_signal() SIGNAL ARRIVES MODE MODE handle_timeout() TIMER EXPIRES remove_handler(callback) EVENT HANDLING REMOVE HANDLER

handle_close()

Participants in the Reactor pattern

 CLEANUP

31 32

The Blob Handler Interface

Using the Reactor in the Blob

Server

 The Blob Handler is the Proxy for commu-

nicating with clients

REGISTERED svc_run

Together with Reactor, it implements the asyn- svc_run {

OBJECTS 4: getq(msg) rtion of the Half-Sync/Half-Async 5:svc(msg) chronous task p o

svc_run pattern

: Blob

Reusable Svc Handler. Handler //

: Blob

class Blob_Handler : public Event_Handler Handler : Blob : Message : Blob { : Event Queue LEVEL LEVEL Handler Handler Processor public:

: Event

// Entry point into Blob Handler. APPLICATION

APPLICATION Handler

int open void { : Event 2: recv_request(msg) virtual

3: putq(msg)

Register with Reactor to handle client input.

Handler //

Reactor::instance ->register_handler

READ_MASK;

1: handle_input() this, }

: Handle protected: LEVEL

LEVEL Table

// Notified by Reactor when client requests arrive. FRAMEWORK

FRAMEWORK

int handle_input void; : Reactor virtual

OS EVENT DEMULTIPLEXING INTERFACE

// Receive and frame client requests.

int recv_request Message_Block &*; LEVEL

LEVEL

SOCK_Stream peer_stream_; // IPC endpoint. KERNEL

KERNEL

};

33 34

Structure of the Active Object

Pattern

The Active Object Pattern

loop { Intent  Client m = actQueue.remove()

Interface dispatch (m) \Decouples metho d execution from metho d invo- { }

ResultHandle m1()

cation and simpli es synchronized access to shared

ResultHandle m2() y concurrent threads" resources b Scheduler ResultHandle m3() dispatch() m1'() Activation m2'() 1 Queue

VISIBLE m3'() 1

This pattern resolves the following forces  insert()

TO

r concurrent communication software: fo remove() CLIENTS 1

1

How to allow blo cking read and write op erations { 1 n

on one endp oint that do not detract from the qual- INVISIBLE y of service of other endp oints it TO Resource Method

CLIENTS Representation Objects

{ How to simplify concurrent access to shared state

{ How to simplify comp osition of indep endent ser-

vices

 The Scheduler determines the sequence that

Method Objects are executed

36 35

Using the Active Object Pattern

in the Blob Server

Collab orati on in the Active

svc_run

Pattern Object REGISTERED svc_run 4: getq(msg) OBJECTS 5:svc(msg) svc_run : Client : Activation : Represent- client : Scheduler Interface Queue ation

INVOKE m1() : Blob Handler: Blob : Message : Blob CREATE METHOD cons(m1') Handler Queue OBJECT : Blob Processor LEVEL RETURN RESULT future() LEVEL : Event Handler CONSTRUCTION HANDLE METHOD OBJECT Handler: Event APPLICATION APPLICATION

/ 2: recv_request(msg) Handler: Event INSERT IN insert(m1') 3: putq(msg) PRIORITY QUEUE Handler

DEQUEUE NEXT remove(m1') METHOD OBJECT EXECUTION SCHEDULING 1: handle_input()

EXECUTE dispatch(m1') : Handle LEVEL RETURN RESULT reply_to_future() LEVEL Table

COMPLETION FRAMEWORK FRAMEWORK : Reactor

OS EVENT DEMULTIPLEXING INTERFACE LEVEL LEVEL KERNEL

KERNEL

37 38

The Blob Pro cessor Class

Using the

 Pro cesses Blob requests using the \Thread-

Po ol" concurrency mo del

 The Blob Processor is implemented as a Sin-

{ Implement the synchronous task portion of the

gleton that is created \on demand"

Half-Sync/Half-Async pattern

Blob_Processor *

class Blob_Processor : public Task {

Blob_Processor::instance void {

public:

// Beware race conditions!

// Singleton access point.

if instance_ == 0 {

static Blob_Processor *instance void;

instance_ = new Blob_Processor;

}

// Pass a request to the .

return instance_;

virtual put Message_Block *;

}

// Event loop for the pool thread

virtual int svc int {

Message_Block *mb = 0; // Message buffer.

 Constructor creates the thread pool

// Wait for messages to arrive.

for ;; {

Blob_Processor::Blob_Processor void {

getq mb; // Inherited from class Task;

Thread_Manager::instance ->spawn_n

// Identify and perform Blob Server

num_threads, THR_FUNC svc_run,

// request processing here...

void * this, THR_NEW_LWP;

}

protected:

Blob_Processor void; // Constructor.

40 39

Using the Double-Checked

The Double-Checked Lo cking

Lo cking Pattern for the Blob

Pattern

Server

 Intent

{ \Ensures atomic initialization of objects and elim-

unnecessary lo cking overhead on each ac- inates if (instance_ == NULL) {

cess" mutex_.acquire (); if (instance_ == NULL) instance_ = new Blob_Processor;

mutex_.release ();

This pattern resolves the following forces:  }

return instance_;

1. Ensures atomic initialization or access to objects,

regardless of thread scheduling order

Blob Processor

Keeps lo cking overhead to a minimum 2. static instance()

static instance_

{ e.g., only lo ck on rst access

Mutex

 Note, this pattern assumes atomic memory

access:: :

41 42

Structure of the

Half-Sync/Half-Async Pattern

Half-Sync/Half-Async Pattern

 Intent SYNC SYNC TASK

TASK 3

\Decouples synchronous I/O from asynchronous

{ 1

I/O in a system to simplify programming e ort without degrading execution eciency"

SYNC TASK LAYER TASK LAYER TASK

SYNCHRONOUS 2

SYNCHRONOUS

 This pattern resolves the following forces

for concurrent communication systems:

1, 4: read(data)

{ How to simplify programming for higher-level com- munication tasks LAYER LAYER MESSAGE QUEUES QUEUEING

QUEUEING

These are p erformed synchronously . 3: enqueue(data)

ASYNC

{ How to ensure ecient lower-level I/O communi- TASK

cation tasks 2: interrupt

These are p erformed asynchronously . EXTERNAL EVENT SOURCES TASK LAYER TASK LAYER ASYNCHRONOUS

ASYNCHRONOUS

43 44

Using the Half-Sync/Half-Async

Collab oration s in the

Pattern in the Blob Server

Half-Sync/Half-Async Pattern

svc_run svc_run svc_run External Async Message Sync Event Source Task Queue Task notification() 4: getq(msg) EXTERNAL EVENT 5:svc(msg) LEVEL LEVEL read(msg) : Blob RECV MSG SYNCH TASK SYNCH TASK Processor

ASYNC PHASE work() PROCESS MSG enqueue(msg) ENQUEUE MSG : Blob read(msg) Handler : Message PHASE DEQUEUE MSG : Blob Queue LEVEL QUEUEING work() LEVEL Handler

QUEUEING : Event : Blob QUEUEING EXECUTE TASK Handler Handler 2: recv_request(msg) : Event SYNC PHASE 3: putq(msg) Handler: Event

Handler

This illustrates input pro cessing output pro-  1: handle_input() : Reactor LEVEL

LEVEL

cessing is similar ASYNC TASK

ASYNC TASK

45 46

Joining Async and Sync Tasks in

The Acceptor Pattern

the Blob Server

 Intent

 The following metho ds form the b oundary

{ \Decouples passive initialization of a service from

the tasks p erformed once the service is initialized"

between the Async and Sync layers

int

Blob_Handler::handle_input void

 This pattern resolves the following forces

{

for network servers using interfaces like so ck-

Message_Block *mb = 0;

ets or TLI:

// Receive and frame message

1. How to reuse passive connection establishment co de

// uses peer_stream_.

for each new service

recv_request mb;

2. How to make the connection establishment co de

// Insert message into the Queue.

portable across platforms that may contain so ck-

Blob_Processor::instance ->put mb;

ets but not TLI, or vice versa

}

// Task entry point.

3. How to ensure that a passive-mo de descriptor is

Blob_Processor::put Message_Block *msg

not accidentally used to read or write data

{

// Insert the message on the Message_Queue

// inherited from class Task.

4. How to enable exible p olicies for creation, con-

putq msg;

nection establishment, and concurrency

}

48 47

Collab orati on in the Acceptor

Pattern

acc : peer_acceptor_ sh: reactor : Server

Acceptor : SOCK Svc_Handler Reactor

of the Acceptor Pattern Structure Acceptor open() INITIALIZE PASSIVE open() ENDPOINT register_handler(acc) REGISTER HANDLER get_handle() EXTRACT HANDLE

Svc Handler PHASE START EVENT LOOP handle_events() ENDPOINT select() Svc Handler INITIALIZATION FOREACH EVENT DO Acceptor handle_input() peer_stream_ peer_acceptor_ CONNECTION EVENT sh = make_svc_handler() open() handle_input() CREATE, ACCEPT, accept_svc_handler (sh) ACTIVATES AND ACTIVATE OBJECT activate_svc_handler (sh) register_handler(sh) PHASE REGISTER HANDLER SERVICE FOR CLIENT I/O get_handle() INITIALIZATION EXTRACT HANDLE Reactor handle_input() DATA EVENT svc() handle_input() PROCESS MSG handle_close() PHASE CLIENT SHUTDOWN SERVICE

PROCESSING SERVER SHUTDOWN handle_close()

 Acceptor is a factory that creates, connects,

and activates a Svc Handler

49 50

The Acceptor Class

Using the Acceptor Pattern in the

 The Acceptor class implements the Acceptor

Blob Server

pattern

// Reusable Factor

: Blob

: Blob : Blob template

: Blob Handler

Acceptor :

Acceptor Handler Handler class

public Service_Object // Subclass of Event_Handler.

: Svc : Svc : Svc {

Handler public:

: Acceptor Handler Handler

// Notified by Reactor when clients connect.

virtual int handle_input void

1: handle_input() {

ACTIVE

The strategy for initializing a SVC_HANDLER. 2: sh = make_svc_handler() : Blob //

CONNECTIONS

ER *sh = new SVC_HANDLER; 3: accept_svc_handler(sh) Handler SVC_HANDL

4: activate_svc_handler(sh)

peer_acceptor_.accept *sh; ; : Svc sh->open PASSIVE LISTENER

: Reactor Handler }

// ...

protected:

// IPC connection factory.

SOCK_Acceptor peer_acceptor_;

}

52 51

The Service Con gurator Pattern

 Intent

The Blob Acceptor Class

{ \Decouples the b ehavior of communication ser-

Interface

vices from the p oint in time at which these services

are con gured into an application or system"

 The Blob Acceptor class accepts connections

and initial i zes Blob Handlers

 This pattern resolves the following forces

for highly exible communication software:

class Blob_Acceptor

: public Acceptor

{ How to defer the selection of a particulartyp e, or

// Inherits handle_input strategy from Acceptor.

aparticular implementation, of a service until very

{

late in the design cycle

public:

// Called when Blob_Acceptor is dynamically linked.

. i.e., at installation-timeor run-time

virtual int init int argc, char *argv;

{ How to build complete applications by comp osing

// Called when Blob_Acceptor is dynamically unlinked.

multiple indep endently develop ed services

virtual int fini void;

{ How to optimize, recon gure, and control the b e-

havior of the service at run-time

54 53

Structure of the Service

Con gurator Pattern

Collab oration in the Service

r Pattern Concrete Con gurato Service Object LAYER LAYER svc : : Service : Service main() : Reactor

APPLICATION Service_Object Config Repository APPLICATION

CONFIGURE Service_Config() FOREACH SVC ENTRY DO process_directives() link_service() Service Service DYNAMICALLY LINK SERVICE init(argc, argv) Object Config INITIALIZE SERVICE register_handler(svc) 1 REGISTER SERVICE suspend() MODE get_handle() EXTRACT HANDLE resume() 1 insert() STORE IN REPOSITORY init() CONFIGURATION A run_event_loop() fini() 1 START EVENT LOOP handle_events() LAYER LAYER info() n FOREACH EVENT DO Service handle_input() 1 INCOMING EVENT CONFIGURATION CONFIGURATION Repository SHUTDOWN EVENT handle_close()

MODE CLOSE SERVICE remove_handler(svc) unlink_service() UNLINK SERVICE fini() remove() EVENT HANDLING Event Handler 1 Reactor LAYER LAYER n REACTIVE

REACTIVE

55 56

Using the Service Con gurator

The Blob Acceptor Class

Pattern in the Blob Server

Implementation

// Initialize service when dynamically linked.

SERVICE : Reactive

Blob_Acceptor::init int argc, char *argv[] Blob Server int CONFIGURATOR

: TP {

RUNTIME : Service

:instance ->parse_args argc, argv; Blob Server Options: Object SHARED

: Service : Service

Set the endpoint into listener mode. OBJECTS //

Repository Object

Acceptor::open local_addr;

: TPR

Initialize the communication endpoint. Blob Server //

: Service

:instance ->register_handler : Reactor Reactor:

Config : Service READ_MASK

Object this,

}

// Terminate service when dynamically unlinked.

int Blob_Acceptor::fini void

{

 Existing service is based on Half-Sync/Half-

// Unblock threads in the pool so they will

Async pattern

// shutdown correctly.

Blob_Processor::instance ->close ;

// Wait for all threads to exit.

 Other versions could be single-threaded or

Thread_Manager::instance ->wait ;

}

use other concurrency strategies:::

57 58

Con guring the Blob Server with

the Service Con gurator

Main Program for Blob Server

 Dynamically con gure and execute the Blob

 The concurrent Blob Server is con gured

Server

and initial i zed via a con guration script

{ Note that this is totally generic!

 cat ./svc.conf

int main int argc, char *argv[]

dynamic TP_Blob_Server Service_Object *

{

blob_server.dll:make_TP_Blob_Server

Service_Config daemon;

"-p $PORT -t $THREADS"

// Initialize the daemon and dynamically

// configure the service.

daemon.open argc, argv;

 Factory function that dynamically allo cates

a Half-Sync/Half-Async Blob Server object

// Loop forever, running services and handling

// reconfigurations.

extern "C" Service_Object *make_TP_Blob_Server void;

daemon.run_event_loop ;

Service_Object *make_TP_Blob_Server void

/* NOTREACHED */

{

}

return new Blob_Acceptor;

// ACE dynamically unlinks and deallocates this object.

}

60 59

The Connector Pattern

Structure of the Connector

 Intent

Pattern

{ \Decouples active initialization of a service from

the task p erformed once a service is initialized" Service

Handler Service Handler

This pattern resolves the following forces  Connector

peer_stream_

r network clients that use interfaces like

fo open() connect(sh, addr)

ets or TLI:

so ck n ACTIVATES 1 complete()

1. How to reuse active connection establishment co de

for each new service HANDLE ASYNC

CONNECTION COMPLETION

2. How to make the connection establishment co de

portable across platforms that may contain so ck- r vice versa

ets but not TLI, o Reactor

3. How to enable exible service concurrency p olicies

4. How to actively establish connections with large

numb er of p eers eciently

62 61

Collab orati on in the Connector

Pattern

Collab orati on in the Connector

Pattern con : peer_stream_ sh: reactor : Client Connector : SOCK Svc_Handler Reactor Connector peer_stream_ connect(sh, addr) / con : sh: reactor : FOREACH CONNECTION Client Connector : SOCK Svc_Handler Reactor connect_svc_handler(sh, addr) Connector INITIATE CONNECTION ASYNC CONNECT FOREACH CONNECTION connect(sh, addr) connect() PHASE PHASE INSERT IN REACTOR register_handler(con) INITIATE CONNECTION connect_svc_handler(sh, addr) INITIATION INITIATION/ INITIATION CONNECTION SYNC CONNECT connect() handle_events() START EVENT LOOP PHASE activate_svc_handler(sh) INITIALIZATION ACTIVATE OBJECT INITIALIZATION select() open() FOREACH EVENT DO handle_output() INSERT IN REACTOR register_handler(sh) CONNECTION COMPLETE activate_svc_handler(sh) SEVICE get_handle() CONNECTION EXTRACT HANDLE PHASE ACTIVATE OBJECT open() handle_events() SERVICE START EVENT LOOP register_handler(sh) INSERT IN REACTOR select() INITIALIZATION FOREACH EVENT DO get_handle() handle_input() EXTRACT HANDLE

PHASE DATA ARRIVES SERVICE

PROCESSING PROCESS DATA svc() handle_input() DATA ARRIVES

PHASE svc() SERVICE PROCESS DATA

PROCESSING

 Synchronous mo de

 Asynchronous mo de

64 63

Bene ts of Design Patterns

Using the Connector in the Blob

Clients

 Design patterns enable large-scale reuse of

software architectures

: Blob : Blob : Blob : Blob Handler Handler Handler Handler: Blob : Blob

Handler

Patterns explicitl y capture exp ert knowledge Handler  : Svc : Svc : Svc : Svc

Handler : Svc Handler Handler

design tradeo s Handler : Svc and Handler Handler

PENDING CONNECTIONS

ACTIVE

Patterns help improve develop er communi- CONNECTIONS : Blob  : Blob Handler

Connector cation : Reactor : Svc

: Connector Handler

 Patterns help ease the transition to object-

oriented technology

65 66

Suggestion s for Using Patterns

E ectively

Drawbacks to Design Patterns

 Do not recast everything as a pattern

 Patterns do not lead to direct co de reuse

{ Instead, develop strategic domain patterns and reuse

existing tactical patterns

 Patterns are deceptively simple

 Institutionalize rewards for developing pat-

terns

 Teams may su er from pattern overload

 Directly involve pattern authors with appli-

 Patterns are validated by exp erience and dis-

cation develop ers and domain exp erts

cussion rather than by automated testing

 Integrating patterns into a software devel-

 Clearly do cument when patterns apply and

opment pro cess is a human-intensive activ-

do not apply

ity

 Manage exp ectations carefully

68 67

Bo oks and Magazines on Patterns

 Bo oks

Conferences and Workshops on

{ Gamma et al., \Design Patterns: Elements of

Reusable Object-Oriented Software" Addison-Wesley,

Patterns

Reading, MA, 1994.

{ \Pattern Languages of Program Design," editors

 1st EuroPLoP

James O. Coplien and Douglas C. Schmidt, Addison-

Wesley, Reading, MA, 1995

{ July 1014, 1996, Kloster Irsee, Germany

 Sp ecial Issues in Journals

 3rd Pattern Languages of Programs Con-

ference

{ \Theory and Practice of Object Systems" guest

editor: Stephen P. Berczuk

{ Septemb er 46, 1996, Monticello, Illinois, USA

{ \Communications of the ACM" guest editors: Dou-

glas C. Schmidt, Ralph Johnson, and Mohamed

Fayad

 Relevant WWW URLs

 Magazines

http://www.cs.wustl.edu/~schmidt/jointPLoP96.html/

http://st-www.cs.uiuc.edu/users/patterns/patterns.html

{ C++ Rep ort and Journal of Object-Oriented Pro-

gramming, columns by Coplien, Vlissides, and De

Souza

70 69

Obtaining ACE

 The ADAPTIVE Communication Environ-

ment ACE is an OO to olkit designed ac-

cording to key network programming pat-

terns

 All source co de for ACE is freely available

{ Anonymously ftp to wuarchive.wustl.edu

{ Transfer the les /languages/c++/ACE/*.gz and

gnu/ACE-documentation/*.gz

 Mailing lists

* [email protected]

* [email protected]

* [email protected]

* [email protected]

 WWW URL

{ http://www.cs.wustl.edu/~schmidt/ACE.html 71