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/
Design patterns and frameworks help to cap-
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 THREAD 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 \inversion of control"
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 scheduling
. 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 Active Object
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 Singleton Pattern
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 thread pool.
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 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 10 14, 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 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++ 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
WWW URL
{ http://www.cs.wustl.edu/~schmidt/ACE.html 71