Download as pdf or txt
Download as pdf or txt
You are on page 1of 18

Design Patterns and Frameworks Motivation

for Object-oriented
Developing ecient, robust, extensible, and
Communication 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.edu/schmidt/
 Design patterns and frameworks help to cap-
schmidt@cs.wustl.edu ture, articulate, and instantiate these suc-
Washington University, St. Louis cessful techniques

1 2

Observations Design Patterns


 Developers of communication software con- Design patterns represent solutions to prob-
front recurring challenges that are largely 
lems that arise when developing software
application-independent within a particular context
{ e.g., service initialization and distribution, error
handling, ow control, event demultiplexing, con- { i.e., \Patterns == problem/solution pairs in a con-
currency control text"

 Patterns capture the static and dynamic struc-


 Successful developers resolve these challenges ture and collaboration among key partici-
by applying appropriate design patterns pants in software designs
{ They are particularly useful for articulating how
and why to resolve non-functional forces
 However, these patterns have traditionally
been either:
1. Locked inside heads of expert developers  Patterns facilitate reuse of successful soft-
ware architectures and designs
2. Buried in source code

3 4
Proxy Pattern Graphical Notation
1: METHOD
: BROKER CALL

4: METHOD : QUOTER OBJECT


RETURN
PROXY
PROCESS : CLASS
2: FORWARD THREAD
REQUEST

3: RESPONSE

CLASS
CLIENT CLASS TEMPLATE UTILITY
: QUOTER CLASS
NETWORK

CLASS
CATEGORY INHERITS INSTANTIATES
SERVER

ABSTRACT
CLASS
CONTAINS USES
A
 Intent: provide a surrogate for another ob-
ject that controls access to it
5 6

Frameworks
More Observations  A framework is:
{ \An integrated collection of components that col-
laborate to produce 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 code (directly)
 Frameworks di er from conventional class
libraries:
 To be productive, developers must also reuse 1. Frameworks are \semi-complete" applications
detailed designs, algorithms, interfaces, im- 2. Frameworks address a particular application do-
plementations, etc. main
3. Frameworks provide \inversion of control"
 Application frameworks are an e ective way
to achieve broad reuse of software
 Typically, applications are developed by in-
heriting from and instantiating framework
components
7 8
Di erences Between Class
Libraries and Frameworks
NETWORKING
Tutorial Outline
APPLICATION
SPECIFIC
LOGIC INVOKES MATH ADTS  Outline key challenges for developing com-
EVENT USER
DATA
munication software
LOOP INTERFACE
BASE

 Present the key reusable design patterns in


CLASS a distributed medical imaging system
LIBRARIES
{ Both single-threaded and multi-threaded solutions
are presented
NETWORKING USER
MATH
INTERFACE
APPLICATION
INVOKES SPECIFIC
LOGIC
CALL
BACKS
EVENT
 Discuss lessons learned from using patterns
LOOP on production software systems
ADTS DATABASE

OBJECT-ORIENTED
FRAMEWORK

9 10

Concurrency vs. Parallelism


Stand-alone vs. Distributed
Application Architectures SERVER

PRINTER maxfdp1
read_fds
CLIENT
COMPUTER
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
 Distributed application development exhibits Sources of Complexity (cont'd)
both inherent and accidental complexity
 Accidental complexity results from limita-
tions with tools and techniques, e.g.,
 Inherent complexity results from fundamen-
tal challenges, e.g., { Low-level tools
{ Distributed systems . e.g., Lack of type-secure, portable, re-entrant,
and extensible system call interfaces and com-
. Latency ponent libraries
. Error handling { Inadequate debugging support
. Service partitioning and load balancing { Widespread use of algorithmic decomposition
{ Concurrent systems . Fine for explaining network programming con-
. Race conditions
cepts and algorithms but inadequate for devel-
oping large-scale distributed applications
. Deadlock avoidance { Continuous rediscovery and reinvention of core con-
. Fair scheduling cepts and components

. Performance optimization and tuning


13 14

OO Contributions
 Concurrent and distributed programming has
traditionally been performed using low-level Distributed Medical Imaging
OS mechanisms, e.g., Example
{ fork/exec
{ Shared memory  This example illustrates the reusable design
{ Signals patterns and framework components used in
{ Sockets and select an OO architecture for a distributed medical
imaging system
{ POSIX pthreads, Solaris threads, Win32 threads

 OO design patterns and frameworks elevate  Application clients uses Blob Servers to store
development to focus on application con- and retrieve medical images
cerns, e.g.,
{ Service functionality and policies  Clients and Servers communicate via a connection-
{ Service con guration oriented transport protocol
{ Concurrent event demultiplexing and event han- { e.g., TCP/IP, IPX/SPX, TP4
dler dispatching
{ Service concurrency and synchronization
15 16
Distributed Electronic Medical Architecture of the Blob Server
Imaging Architecture
MODALITIES
BLOB SERVER
LOCAL
(CT, MR, CR) svc_run svc_run
STORE svc_run
svc_run
ATM
LAN

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

ATM ATM : Blob : Blob : Blob


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

LOCATION
SERVICE
SERVICE
CENTRAL
STORE
MODALITIES
(CT, MR, CR) * Manage short-term and long-term blob persistence
17
* Respond to queries from Blob Locators
18

Design Patterns in the Blob Tactical Patterns


Server  Proxy
{ \Provide a surrogate or placeholder for another
Thread-per object to control access to it"
Thread-per Session
Request
Acceptor
 Strategy
Active Object
Thread
Connector
{ \De ne a family of algorithms, encapsulate each
Pool one, and make them interchangeable"
Half-Sync/ Service
Half-Async Configurator  Adapter
STRATEGIC { \Convert the interface of a class into another in-
PATTERNS Reactor Double Checked terface client expects"
Locking

TACTICAL
PATTERNS Proxy Strategy Adapter Singleton  Singleton
{ \Ensure a class only has one instance and provide
a global point of access to it"
19 20
Concurrency Patterns
 Reactor
{ \Decouples event demultiplexing and event han- Concurrency Architecture
dler dispatching from application services performed
in response to events" Patterns
 Active Object  Thread-per-Request
{ \Decouples method execution from method invo- { \Allows each client request to run concurrently"
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-per-Session
{ \Allows each client session to run concurrently"
 Double-Checked Locking Pattern
{ \Ensures atomic initialization of objects and elim-
inates unnecessary locking overhead on each ac-
cess"
21 22

Service Initialization Patterns Concurrency Patterns in the Blob


Server
 Connector
{ \Decouples active connection establishment from  The following example illustrates the design
the service performed once the connection is es- patterns and framework components in an
tablished"
OO implementation of a concurrent Blob
Server
 Acceptor
{ \Decouples passive connection establishment from  There are various architectural patterns for
the service performed once the connection is es- structuring concurrency in a Blob Server
tablished"
1. Reactive

 Service Con gurator 2. Thread-per-request


{ \Decouples the behavior of network services from 3. Thread-per-session
point in time at which services are con gured into
an application" 4. Thread-pool

23 24
Reactive Blob Server Architecture Thread-per-Request Blob Server
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
: Reactor Processor
Processor
: Reactor

6: PROCESS BLOB REQUEST


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

CLIENT
CLIENT CLIENT CLIENT
CLIENT CLIENT

25 26

Thread-per-Session Blob Server Thread-Pool Blob Server


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

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

27 28
The ADAPTIVE Communication
Environment (ACE) The Reactor Pattern
 Intent
\Decouples event demultiplexing and event han-
DISTRIBUTED GATEWAY TOKEN LOGGING NAME TIME
SERVICES SERVER SERVER SERVER SERVER SERVER
{
dler dispatching from the services performed in re-
FRAMEWORKS
AND CLASS
ACCEPTOR CONNECTOR
SERVICE
HANDLER
CORBA
HANDLER
sponse to events"
CATEGORIES
ADAPTIVE SERVICE EXECUTIVE (ASX)

THREAD LOG SERVICE SHARED


C++
WRAPPERS
MANAGER MSG CONFIG- MALLOC
 This pattern resolves the following forces
for event-driven software:
REACTOR URATOR
SYNCH SPIPE SOCK_SAP/ FIFO MEM SYSV
WRAPPERS SAP TLI_SAP SAP MAP WRAPPERS

OS ADAPTATION LAYER
C
APIS
THREAD STREAM SOCKETS/
TLI
NAMED SELECT/ DYNAMIC MEMORY SYSTEM
V IPC { How to demultiplex multiple types of events from
multiple sources of events eciently within a single
LIBRARY PIPES PIPES POLL LINKING MAPPING

thread of control
PROCESS/THREAD COMMUNICATION VIRTUAL MEMORY
SUBSYSTEM SUBSYSTEM SUBSYSTEM

GENERAL UNIX AND WIN32 SERVICES

{ How to extend application behavior without requir-


 A set of C++ wrappers and frameworks ing changes to the event dispatching framework
based on common design patterns

29 30

Collaboration 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 (); AP
INITIALIZATION

if (h is signal handler)
Event_Handler
PL
DE ICA
Reactor()
table[h]->handle_signal (); PE T INITIALIZE
} ND ION-
EN
this->expire_timers (); handle_input() T register_handler(callback)
MODE

AP
handle_output() P
IN LICA
REGISTER HANDLER
DE
handle_signal() PE TION get_handle()
ND -
handle_timeout() EN
T EXTRACT HANDLE
n get_handle() n handle_events()
A START EVENT LOOP
1 1
1
FOREACH EVENT DO
select()
Reactor Timer_Queue
EVENT HANDLING

1 handle_input()
handle_events() 1 n DATA ARRIVES
schedule_timer(h)
register_handler(h) Handles cancel_timer(h)
remove_handler(h)
expire_timer(h)
handle_output()
MODE

expire_timers() OK TO SEND
n
1 1 handle_signal()
SIGNAL ARRIVES
handle_timeout()
TIMER EXPIRES
remove_handler(callback)
REMOVE HANDLER

 Participants in the Reactor pattern CLEANUP


handle_close()

31 32
Using the Reactor in the Blob The Blob Handler Interface
Server  The Blob Handler is the Proxy for commu-
nicating with clients
REGISTERED
svc_run
svc_run { Together with Reactor, it implements the asyn-
OBJECTS 4: getq(msg) chronous task portion of the Half-Sync/Half-Async
5:svc(msg) svc_run pattern
APPLICATION

: Blob
// Reusable Svc Handler.
Handler
: Blob
LEVEL

class Blob_Handler : public Event_Handler


Handler : Message {
: Event : Blob Queue
: Blob
Handler Processor public:
Handler
: Event // Entry point into Blob Handler.
Handler virtual int open (void) {
: Event 2: recv_request(msg)
Handler3: putq(msg) // Register with Reactor to handle client input.
Reactor::instance ()->register_handler
FRAMEWORK

(this, READ_MASK);
1: handle_input() }
LEVEL

: Handle
Table protected:
// Notified by Reactor when client requests arrive.
: Reactor virtual int handle_input (void);

OS EVENT DEMULTIPLEXING INTERFACE // Receive and frame client requests.


KERNEL
LEVEL

int recv_request (Message_Block &*);

SOCK_Stream peer_stream_; // IPC endpoint.


};

33 34

Structure of the Active Object


The Active Object Pattern Pattern
 Intent Client
loop {
m = actQueue.remove()
{ \Decouples method execution from method invo- Interface
}
dispatch (m)

cation and simpli es synchronized access to shared ResultHandle m1()


resources by concurrent threads" ResultHandle m2()
ResultHandle m3()
Scheduler
dispatch()
m1'() Activation
m2'() Queue
 This pattern resolves the following forces VISIBLE m3'()
1
1
for concurrent communication software: TO
CLIENTS 1
insert()
remove()
1
{ How to allow blocking read and write operations n
on one endpoint that do not detract from the qual- INVISIBLE
1
ity of service of other endpoints TO Resource Method
CLIENTS Representation Objects
{ How to simplify concurrent access to shared state
{ How to simplify composition of independent ser-
vices  The Scheduler determines the sequence that
Method Objects are executed

35 36
Using the Active Object Pattern
in the Blob Server
Collaboration in the Active
Object Pattern REGISTERED
4: getq(msg)
svc_run svc_run
OBJECTS 5:svc(msg)
svc_run
: Client : Activation : Represent-
client : Scheduler
Interface Queue ation

APPLICATION
METHOD OBJECT
CONSTRUCTION

m1() : Blob

LEVEL
INVOKE
: Blob
Handler : Message : Blob
CREATE METHOD cons(m1') Handler Queue
Processor
OBJECT : Blob
RETURN RESULT future() : Event Handler
HANDLE
: Event
Handler
Handler 2: recv_request(msg)
: Event
SCHEDULING/
EXECUTION

INSERT IN insert(m1') 3: putq(msg)


PRIORITY QUEUE Handler
DEQUEUE NEXT remove(m1')

FRAMEWORK
METHOD OBJECT
1: handle_input()

LEVEL
COMPLETION

EXECUTE dispatch(m1') : Handle


RETURN RESULT reply_to_future() Table

: Reactor
OS EVENT DEMULTIPLEXING INTERFACE

KERNEL
LEVEL
37 38

The Blob Processor Class


Using the Singleton Pattern
 Processes Blob requests using the \Thread-
Pool" concurrency model
 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
class Blob_Processor : public Task { Blob_Processor *
public: Blob_Processor::instance (void) {
// Singleton access point. // Beware race conditions!
static Blob_Processor *instance (void); if (instance_ == 0) {
instance_ = new Blob_Processor;
// Pass a request to the thread pool. }
virtual put (Message_Block *); return instance_;
}
// 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.

39 40
The Double-Checked Locking Using the Double-Checked
Pattern Locking Pattern for the Blob
Server
 Intent
{ \Ensures atomic initialization of objects and elim-
inates unnecessary locking overhead on each ac- 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
2. Keeps locking overhead to a minimum
static instance()
{ e.g., only lock on rst access static instance_

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
SYNCHRONOUS
TASK LAYER

{ \Decouples synchronous I/O from asynchronous TASK 1


TASK 3

I/O in a system to simplify programming e ort


without degrading execution eciency"
SYNC
TASK 2
 This pattern resolves the following forces
for concurrent communication systems:
QUEUEING
LAYER

1, 4: read(data)
{ How to simplify programming for higher-level com-
munication tasks
MESSAGE QUEUES

. These are performed synchronously 3: enqueue(data)


ASYNCHRONOUS
TASK LAYER

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


cation tasks TASK 2: interrupt

. These are performed asynchronously EXTERNAL


EVENT SOURCES

43 44
Using the Half-Sync/Half-Async
Collaborations in the Pattern in the Blob Server
Half-Sync/Half-Async Pattern
svc_run svc_run svc_run

SYNCH TASK
External Async Message Sync

LEVEL
Event Source Task Queue Task
notification() 4: getq(msg)
EXTERNAL EVENT 5:svc(msg)
SYNC QUEUEING ASYNC
PHASE

read(msg) : Blob
RECV MSG
Processor
work()
PROCESS MSG

QUEUEING
enqueue(msg)
PHASE PHASE

: Blob

LEVEL
ENQUEUE MSG
read(msg) Handler : Message
DEQUEUE MSG : Blob Queue
work() Handler
: Event : Blob
EXECUTE TASK
Handler Handler
2: recv_request(msg)
: Event
3: putq(msg)
Handler
: Event
Handler

ASYNC TASK
LEVEL
 This illustrates input processing (output pro- 1: handle_input() : Reactor
cessing is similar)

45 46

Joining Async and Sync Tasks in The Acceptor Pattern


the Blob Server
 Intent
 The following methods form the boundary { \Decouples passive initialization of a service from
between the Async and Sync layers the tasks performed once the service is initialized"

int
Blob_Handler::handle_input (void)  This pattern resolves the following forces
{ for network servers using interfaces like sock-
Message_Block *mb = 0; ets or TLI:
// Receive and frame message
1. How to reuse passive connection establishment code
// (uses peer_stream_).
recv_request (mb);
for each new service
// Insert message into the Queue. 2. How to make the connection establishment code
Blob_Processor::instance ()->put (mb); portable across platforms that may contain sock-
} ets but not TLI, or vice versa
// Task entry point.
3. How to ensure that a passive-mode 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 policies for creation, con-
putq (msg); nection establishment, and concurrency
}

47 48
Collaboration in the Acceptor
Pattern
peer_acceptor_

Structure of the Acceptor Pattern


acc : sh: reactor :
Server : SOCK
Acceptor Svc_Handler Reactor
Acceptor
open()
INITIALIZE PASSIVE open()

PROCESSING INITIALIZATION INITIALIZATION


ENDPOINT

ENDPOINT
register_handler(acc)

PHASE
REGISTER HANDLER

EXTRACT HANDLE
get_handle()
Svc Handler START EVENT LOOP handle_events()

Svc Handler Acceptor FOREACH EVENT DO select()


handle_input()
peer_stream_ peer_acceptor_ CONNECTION EVENT
sh = make_svc_handler()
ES
IVAT

SERVICE
CREATE, ACCEPT,
open() accept_svc_handler (sh)

PHASE
ACT handle_input() AND ACTIVATE OBJECT activate_svc_handler (sh)
register_handler(sh)
REGISTER HANDLER
FOR CLIENT I/O
get_handle()
EXTRACT HANDLE

Reactor DATA EVENT


handle_input()

SERVICE

PHASE
svc()
handle_input() PROCESS MSG

CLIENT SHUTDOWN
handle_close()

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
Blob Server  The Acceptor class implements the Acceptor
pattern
// Reusable Factor
: Blob : Blob template <class SVC_HANDLER>
: Blob : Blob
Handler Handler class Acceptor :
Acceptor Handler
public Service_Object // Subclass of Event_Handler.
: Svc {
: Svc : Svc
Handler Handler Handler public:
: Acceptor // Notified by Reactor when clients connect.
virtual int handle_input (void)
1: handle_input() {
2: sh = make_svc_handler() ACTIVE
: Blob // The strategy for initializing a SVC_HANDLER.
3: accept_svc_handler(sh) CONNECTIONS
Handler SVC_HANDLER *sh = new SVC_HANDLER;
4: activate_svc_handler(sh) peer_acceptor_.accept (*sh);
: Svc sh->open ();
PASSIVE LISTENER
Handler }
: Reactor // ...

protected:
// IPC connection factory.
SOCK_Acceptor peer_acceptor_;
}

51 52
The Service Con gurator Pattern
The Blob Acceptor Class  Intent
Interface { \Decouples the behavior of communication ser-
vices from the point in time at which these services
are con gured into an application or system"
 The Blob Acceptor class accepts connections
and initializes Blob Handlers  This pattern resolves the following forces
for highly exible communication software:
class Blob_Acceptor
: public Acceptor<Blob_Handler> { How to defer the selection of a particular type, or
// Inherits handle_input() strategy from Acceptor. a particular implementation, of a service until very
{ late in the design cycle
public:
// Called when Blob_Acceptor is dynamically linked.
virtual int init (int argc, char *argv);
. i.e., at installation-time or run-time
// Called when Blob_Acceptor is dynamically unlinked. { How to build complete applications by composing
virtual int fini (void); multiple independently developed services
{ How to optimize, recon gure, and control the be-
havior of the service at run-time

53 54

Structure of the Service


Con gurator Pattern
Collaboration in the Service
Con gurator Pattern
APPLICATION

Concrete
LAYER

Service Object
svc : : Service : Service
main() : Reactor
Service_Object Config Repository
CONFIGURE Service_Config()
FOREACH SVC ENTRY DO process_directives()
CONFIGURATION

Service Service DYNAMICALLY LINK


SERVICE
link_service()
init(argc, argv)
Object Config
MODE

INITIALIZE SERVICE
CONFIGURATION

register_handler(svc)
suspend() 1 REGISTER SERVICE

EXTRACT HANDLE
get_handle()
resume() 1 insert()
LAYER

STORE IN REPOSITORY
init() A
run_event_loop()
fini() 1 START EVENT LOOP

info() n handle_events()
EVENT HANDLING

FOREACH EVENT DO
Service handle_input()
1 INCOMING EVENT
Repository
MODE

SHUTDOWN EVENT handle_close()


CLOSE SERVICE remove_handler(svc)

UNLINK SERVICE
unlink_service()
fini()
REACTIVE

remove()
LAYER

Event
Handler n 1 Reactor

55 56
Using the Service Con gurator
Pattern in the Blob Server The Blob Acceptor Class
Implementation
// Initialize service when dynamically linked.

SERVICE : Reactive
Blob Server int Blob_Acceptor::init (int argc, char *argv[])
CONFIGURATOR
: TP {
RUNTIME : Service
Blob Server Options::instance ()->parse_args (argc, argv);
SHARED Object
: Service : Service // Set the endpoint into listener mode.
OBJECTS
Repository Object Acceptor::open (local_addr);
: TPR
Blob Server // Initialize the communication endpoint.
: Service : Reactor Reactor::instance ()->register_handler
Config : Service (this, READ_MASK)
Object }

// 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
 The concurrent Blob Server is con gured  Dynamically con gure and execute the Blob
Server
and initialized via a con guration script
{ Note that this is totally generic!
% cat ./svc.conf
dynamic TP_Blob_Server Service_Object * int main (int argc, char *argv[])
blob_server.dll:make_TP_Blob_Server() {
"-p $PORT -t $THREADS" Service_Config daemon;

// Initialize the daemon and dynamically


// configure the service.
 Factory function that dynamically allocates daemon.open (argc, argv);

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.
}

59 60
The Connector Pattern
 Intent Structure of the Connector
{ \Decouples active initialization of a service from Pattern
the task performed once a service is initialized"
Service
Service Handler
Handler
 This pattern resolves the following forces Connector
for network clients that use interfaces like peer_stream_
sockets or TLI: open()
n ACTIVATES 1
connect(sh, addr)
complete()
1. How to reuse active connection establishment code
for each new service
HANDLE ASYNC
CONNECTION COMPLETION
2. How to make the connection establishment code
portable across platforms that may contain sock-
ets but not TLI, or vice versa Reactor
3. How to enable exible service concurrency policies
4. How to actively establish connections with large
number of peers eciently

61 62

Collaboration in the Connector


Collaboration in the Connector Pattern
Pattern con : peer_stream_ sh: reactor :
Client
Connector : SOCK Svc_Handler Reactor
Connector
connect(sh, addr)
CONNECTION

peer_stream_ FOREACH CONNECTION


INITIATION

con : sh: reactor :


CONNECTION INITIATION/
INITIATION/

Client : SOCK Svc_Handler


SEVICE INITIALIZATION

PHASE

Connector Reactor INITIATE CONNECTION connect_svc_handler(sh, addr)


Connector
FOREACH CONNECTION connect(sh, addr) ASYNC CONNECT connect()
connect_svc_handler(sh, addr) INSERT IN REACTOR register_handler(con)
INITIATE CONNECTION
PHASE

SYNC CONNECT connect() handle_events()


START EVENT LOOP
activate_svc_handler(sh)
INITIALIZATION

ACTIVATE OBJECT
select()
open() FOREACH EVENT DO
SERVICE

handle_output()
PHASE

INSERT IN REACTOR register_handler(sh) CONNECTION COMPLETE


get_handle() activate_svc_handler(sh)
EXTRACT HANDLE
ACTIVATE OBJECT open()
handle_events() register_handler(sh)
PROCESSING

START EVENT LOOP


SERVICE

INSERT IN REACTOR
select()
PHASE

FOREACH EVENT DO get_handle()


handle_input() EXTRACT HANDLE
PROCESSING

DATA ARRIVES
SERVICE
PHASE

PROCESS DATA svc() handle_input()


DATA ARRIVES

PROCESS DATA svc()

 Synchronous mode
 Asynchronous mode
63 64
Using the Connector in the Blob Bene ts of Design Patterns
Clients  Design patterns enable large-scale reuse of
software architectures
: Blob : Blob : Blob
Handler: Blob : Blob Handler Handler

: Svc
Handler
Handler
: Svc : Svc
: Blob
Handler  Patterns explicitly capture expert knowledge
Handler: Svc : Svc
Handler
Handler
Handler Handler
: Svc and design tradeo s
Handler
PENDING

Patterns help improve developer communi-


CONNECTIONS
A
C TIVE
CONNECTIONS : Blob 
: Blob
Connector
Handler
cation
: Svc
: Connector
: Reactor Handler

 Patterns help ease the transition to object-


oriented technology

65 66

Suggestions for Using Patterns


Drawbacks to Design Patterns E ectively
 Do not recast everything as a pattern
 Patterns do not lead to direct code reuse { Instead, develop strategic domain patterns and reuse
existing tactical patterns
 Patterns are deceptively simple
 Institutionalize rewards for developing pat-
 Teams may su er from pattern overload terns

 Patterns are validated by experience and dis-  Directly involve pattern authors with appli-
cussion rather than by automated testing cation developers and domain experts

 Integrating patterns into a software devel-  Clearly document when patterns apply and
opment process is a human-intensive activ- do not apply
ity
 Manage expectations carefully
67 68
Books and Magazines on Patterns
Books

{ Gamma et al., \Design Patterns: Elements of
Conferences and Workshops on
Reusable Object-Oriented Software" Addison-Wesley,
Reading, MA, 1994.
Patterns
{ \Pattern Languages of Program Design," editors  1st EuroPLoP
James O. Coplien and Douglas C. Schmidt, Addison-
Wesley, Reading, MA, 1995 { July 10,14, 1996, Kloster Irsee, Germany

 Special Issues in Journals


 3rd Pattern Languages of Programs Con-
{ \Theory and Practice of Object Systems" (guest ference
editor: Stephen P. Berczuk)
{ September 4,6, 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/jointPLoP,96.html/
http://st-www.cs.uiuc.edu/users/patterns/patterns.html
{ C++ Report and Journal of Object-Oriented Pro-
gramming, columns by Coplien, Vlissides, and De
Souza
69 70

Obtaining ACE
 The ADAPTIVE Communication Environ-
ment (ACE) is an OO toolkit designed ac-
cording to key network programming pat-
terns
 All source code 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
* ace-users@cs.wustl.edu
* ace-users-request@cs.wustl.edu
* ace-announce@cs.wustl.edu
* ace-announce-request@cs.wustl.edu
 WWW URL
{ http://www.cs.wustl.edu/~schmidt/ACE.html
71

You might also like