205
Pattern-Oriented Software Pattern-Oriented Software Architectures Architectures Patterns & Frameworks for Patterns & Frameworks for Concurrent & Distributed Concurrent & Distributed Systems Systems Dr. Douglas C. Schmidt [email protected] http://www.dre.vanderbilt.edu/~schmidt/

Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

  • Upload
    adonica

  • View
    36

  • Download
    0

Embed Size (px)

DESCRIPTION

Pattern-Oriented Software Architectures Patterns & Frameworks for Concurrent & Distributed Systems. Dr. Douglas C. Schmidt [email protected] http://www.dre.vanderbilt.edu/~schmidt/. Tutorial Motivation. Stand-alone Architecture. Networked Architecture. - PowerPoint PPT Presentation

Citation preview

Page 1: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

Pattern-Oriented Software Pattern-Oriented Software

ArchitecturesArchitecturesPatterns & Frameworks for Patterns & Frameworks for

Concurrent & Distributed SystemsConcurrent & Distributed Systems Dr. Douglas C. Schmidt

[email protected]://www.dre.vanderbilt.edu/~schmidt/

Page 2: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

2

Tutorial Motivation

Stand-alone Architecture

• Building robust, efficient, & extensible concurrent & networked applications is hard•e.g., we must address many complex topics that are less problematic for non-concurrent, stand-alone applications

Observations

Networked Architecture

•Fortunately, there are reusable solutions to many common challenges, e.g.:

• Connection mgmt & event demuxing• Service initialization• Error handling & fault tolerance • Flow & congestion control• Distribution• Concurrency, scheduling, & synchronization • Persistence

Page 3: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

3

Tutorial Outline

OO techniques & language features:

•Frameworks & components, which embody reusable software middleware & application implementations

•Patterns (25+), which embody reusable software architectures & designs

•OO language features, e.g., classes, dynamic binding & inheritance, parameterized types

Cover OO techniques & language features that enhance software quality

Modalitiese.g., MRI, CT, CR,

Ultrasound, etc.

Modalitiese.g., MRI, CT, CR,

Ultrasound, etc.

Tutorial Organization

1. Technology trends & background

2. Concurrent & network challenges & solution approaches

3. Case studies

4. Wrap-up

Page 4: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

4

Technology Trends (1/4)

Information technology is being commoditized • i.e., hardware & software are getting cheaper, faster, & (generally) better at a fairly predictable rate

These advances stem largely from standard hardware & software APIs & protocols, e.g.:

• TCP/IP, GSM, Link16

• POSIX, Windows, & VMs

• Middleware & component models

• Intel x86 & Power PC chipsets

• Quality of service (QoS) aspects

Page 5: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

5

Technology Trends (2/4)

Process Automation Quality Control

Avionics Mission Computing

Modalitiese.g., MRI, CT, CR,

Ultrasound, etc.

Electronic Medical Imaging

Software Defined Radio

Hot Rolling Mills

Growing acceptance of a network-centric component paradigm• i.e., distributed applications with a range of QoS needs are constructed by integrating components & frameworks via various communication mechanisms

Page 6: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

6

Technology Trends (3/4)

• Components encapsulate application “business” logic

• Components interact via ports•Provided interfaces, e.g.,facets•Required connection points, e.g., receptacles

•Event sinks & sources•Attributes

• Containers provide execution environment for components with common operating requirements

• Components/containers can also•Communicate via a middleware bus and

•Reuse common middleware services

Component middleware is maturing & becoming pervasive

SecurityReplication NotificationPersistence

SchedulingA/V Streaming Load Balancing

Container

… …

Middleware Bus

Container

Page 7: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

7

•e.g., standard technologies are emerging that can:1. Model2. Analyze3. Synthesize & optimize4. Provision & deploy

multiple layers of QoS-enabled middleware & applications

•These technologies are guided by patterns & implemented by component frameworks

•Partial specialization is essential for inter-/intra-layer optimization

Middleware

MiddlewareServices

DRE Applications

Operating Sys& Protocols

Hardware & Networks

<CONFIGURATION_PASS> <HOME> <…> <COMPONENT> <ID> <…></ID> <EVENT_SUPPLIER> <…events this component supplies…> </EVENT_SUPPLIER> </COMPONENT> </HOME></CONFIGURATION_PASS>

<CONFIGURATION_PASS> <HOME> <…> <COMPONENT> <ID> <…></ID> <EVENT_SUPPLIER> <…events this component supplies…> </EVENT_SUPPLIER> </COMPONENT> </HOME></CONFIGURATION_PASS>

Distributedsystem

Goal is not to replace programmers per se – it is to provide higher-level domain-specific languages for middleware developers & users

Model driven development is integrating generative software technologies with QoS-enabled component middleware

Technology Trends (4/4)

Page 8: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

8

The Evolution of Middleware

There are multiple COTS middleware layers & research/business

opportunities

Historically, mission-critical apps were built directly atop hardware•Tedious, error-prone, & costly over lifecycles

Standards-based COTS middleware helps:•Control end-to-end resources & QoS•Leverage hardware & software technology advances

•Evolve to new environments & requirements

•Provide a wide array of reusable, off-the-shelf developer-oriented services

There are layers of middleware, just like there are layers of networking protocols

Hardware

Domain-SpecificServices

CommonMiddleware Services

DistributionMiddleware

Host InfrastructureMiddleware

& OS

Operating Systems & Protocols

Applications

Page 9: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

9

Operating System & Protocols•Operating systems & protocols provide mechanisms to manage endsystem resources, e.g.,•CPU scheduling & dispatching•Virtual memory management•Secondary storage, persistence, & file systems•Local & remote interprocess communication (IPC)

•OS examples•UNIX/Linux, Windows, VxWorks, QNX, etc.

•Protocol examples•TCP, UDP, IP, SCTP, RTP, etc.

RTP

DNS

HTTP

UDP TCP

IP

TELNET

Ethernet ATM FDDI

Fibre Channel

FTP

INTERNETWORKING ARCH

TFTP

20th Century

Win2K Linux LynxOS

Solaris VxWorks

Middleware

MiddlewareServices

MiddlewareApplications

MIDDLEWARE ARCH

21st Century

Page 10: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

10 www.cs.wustl.edu/~schmidt/ACE.html

Host Infrastructure Middleware•Host infrastructure middleware encapsulates & enhances native OS mechanisms to create reusable network programming components•These components abstract away many tedious & error-prone aspects of low-level OS APIs

Domain-SpecificServices

CommonMiddleware Services

DistributionMiddleware

Host InfrastructureMiddleware

Synchronization

MemoryManagement

PhysicalMemoryAccess

AsynchronousEvent Handling

Scheduling

AsynchronousTransfer of

Control

www.rtj.org

•Examples•Java Virtual Machine (JVM), Common Language Runtime (CLR), ADAPTIVE Communication Environment (ACE)

Page 11: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

11

Distribution Middleware•Distribution middleware defines higher-level distributed programming models whose reusable APIs & components automate & extend native OS capabilities

Domain-SpecificServices

CommonMiddleware Services

DistributionMiddleware

Host InfrastructureMiddleware

•Distribution middleware avoids hard-coding client & server application dependencies on object location, language, OS, protocols, & hardware

InterfaceRepository

IDLCompiler

ImplementationRepository

ClientOBJREF

Object(Servant)

in argsoperation()out args +

return

DIIIDL

STUBSORB

INTERFACE

IDLSKEL

DSI

Object Adapter

ORB CORE GIOP/IIOP/ESIOPS

•Examples•OMG CORBA, Sun’s Remote Method Invocation (RMI), Microsoft’s Distributed Component Object Model (DCOM)

Page 12: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

12

Common Middleware Services•Common middleware services augment distribution middleware by defining higher-level domain-independent services that focus on programming “business logic”

Domain-SpecificServices

CommonMiddleware Services

DistributionMiddleware

Host InfrastructureMiddleware

•Common middleware services support many recurring distributed system capabilities, e.g.,•Transactional behavior

•Authentication & authorization,

•Database connection pooling & concurrency control

•Active replication

•Dynamic resource management

•Examples•CORBA Component Model & Object Services, Sun’s J2EE, Microsoft’s .NET

Page 13: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

13

Domain-Specific Middleware

Modalitiese.g., MRI, CT, CR,

Ultrasound, etc.

Siemens MED Syngo•Common software platform for distributed electronic medical systems

•Used by all ~13 Siemens MED business units worldwide

•Domain-specific middleware services are tailored to the requirements of particular domains, such as telecom, e-commerce, health care, process automation, or aerospace

Domain-SpecificServices

CommonMiddleware Services

DistributionMiddleware

Host InfrastructureMiddleware

Boeing Bold Stroke • Common software platform for Boeing avionics mission computing systems

•Examples

Page 14: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

14

•More emphasis on integration rather than programming

• Increased technology convergence & standardization

•Mass market economies of scale for technology & personnel

•More disruptive technologies & global competition

•Lower priced--but often lower quality--hardware & software components

•The decline of internally funded R&D

•Potential for complexity cap in next-generation complex systems

Consequences of COTS & IT Commoditization

Not all trends bode well for long-term competitiveness of traditional R&D leaders

Ultimately, competitiveness depends on success of long-term R&D on complex distributed real-time & embedded (DRE) systems

Page 15: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

15

Why middleware-centric reuse works1.Hardware advances

•e.g., faster CPUs & networks2.Software/system architecture

advances•e.g., inter-layer optimizations & meta-programming mechanisms

3.Economic necessity•e.g., global competition for customers & engineers

Why We are Succeeding NowRecent synergistic advances in fundamental technologies & processes:

Revolutionary changes in software process & methods: Open-source, refactoring, agile methods, advanced V&V techniques, model-driven development

Patterns & Pattern Languages: Generate software architectures by capturing recurring structures & dynamics & by resolving design forces

Standards-based QoS-enabled Middleware: Pluggable service & micro-protocol components & reusable “semi-complete” application frameworks

Page 16: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

16

Example:

Applying COTS in Real-time Avionics

Key System Characteristics• Deterministic & statistical deadlines

• ~20 Hz• Low latency & jitter

• ~250 usecs• Periodic & aperiodic processing• Complex dependencies• Continuous platform upgrades

• Test flown at China Lake NAWS by Boeing OSAT II ‘98, funded by OS-JTF• www.cs.wustl.edu/~schmidt/TAO-boeing.html

• Also used on SOFIA project by Raytheon• sofia.arc.nasa.gov

• First use of RT CORBA in mission computing• Drove Real-time CORBA standardization

• Test flown at China Lake NAWS by Boeing OSAT II ‘98, funded by OS-JTF• www.cs.wustl.edu/~schmidt/TAO-boeing.html

• Also used on SOFIA project by Raytheon• sofia.arc.nasa.gov

• First use of RT CORBA in mission computing• Drove Real-time CORBA standardization

Key Results

Goals• Apply COTS & open systems to mission-critical real-time avionics

Page 17: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

17

Time-critical targets require immediate response because:•They pose a clear and present danger to friendly forces &•Are highly lucrative, fleeting targets of opportunity

Example:

Applying COTS to Time-Critical Targets

A d a p t e d f r o m “ T h e F u t u r e o f A W A C S ” ,b y L t C o l J o e C h a p a

J o i n t F o r c e sG l o b a l I n f o G r i d

J o i n t F o r c e sG l o b a l I n f o G r i d C h a l le n g e

is t o m a k e t h is p o s s ib le !

Challenges are also relevant to TBMD & NMD

Goals• Detect, identify, track, & destroy time-critical targets

• Real-time mission-critical sensor-to-shooter needs

• Highly dynamic QoS requirements & environmental conditions

• Multi-service & asset coordination

Key System Characteristics

Key Solution Characteristics•Efficient & scalable•Affordable & flexible•COTS-based

•Efficient & scalable•Affordable & flexible•COTS-based

•Adaptive & reflective•High confidence •Safety critical

•Adaptive & reflective•High confidence •Safety critical

Page 18: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

Example: Applying COTS to Large-scale Routers

IOM

IOM

IOM

IOM

IOM

IOM

IOM

IOM

IOM

IOM

IOM

IOM

IOM

IOM

IOM

IOM

IOM

IOM

BSE

BSE

BSE

BSE

BSE

BSE

BSEBSE

BSEGoal•Switch ATM cells + IP packets at terabit rates

Key Software Solution Characteristics

•High confidence & scalable computing architecture•Networked embedded processors•Distribution middleware•FT & load sharing•Distributed & layered resource management

•Affordable, flexible, & COTS

•High confidence & scalable computing architecture•Networked embedded processors•Distribution middleware•FT & load sharing•Distributed & layered resource management

•Affordable, flexible, & COTS

Key System Characteristics•Very high-speed WDM links

•102/103 line cards•Stringent requirements for availability

•Multi-layer load balancing, e.g.:•Layer 3+4•Layer 5

www.arl.wustl.edu

Page 19: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

Example: Applying COTS to Software Defined Radios

Key Software Solution Characteristics

• Transitioned to BAE systems for the Joint Tactical Radio Systems • Programmable radio with waveform-specific components• Uses CORBA component middleware based on ACE+TAO

• Transitioned to BAE systems for the Joint Tactical Radio Systems • Programmable radio with waveform-specific components• Uses CORBA component middleware based on ACE+TAO

www.omg.org/docs/swradio Core Framework (CF)

Commercial Off-the-Shelf(COTS)

Applications

OE

Red Hardware Bus

CFServices &

Applications

CORBA ORB &Services

(Middleware)

Network Stacks & Serial Interface Services

Board Support Package (Bus Layer)

Black Hardware Bus

CFServices &

Applications

CORBA ORB &Services

(Middleware)

Network Stacks & Serial Interface Services

Board Support Package (Bus Layer)

Operating System

Core Framework IDL

Non-CORBAModem

Components

Non-CORBASecurity

Components

Non-CORBA I/O

Components

RF

ModemComponents

Link, NetworkComponents

SecurityComponents

ModemAdapter

SecurityAdapter

SecurityAdapter

I/OAdapter

I/OComponents

MAC API LLC/Network API LLC/Network API

Link, NetworkComponents

Security API

Operating System

Physical API

I/O API

(“Logical Software Bus” via CORBA)

Page 20: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

20

Example:

Applying COTS to Hot Rolling MillsGoals• Control the processing of molten steel moving through a hot rolling mill in real-time

System Characteristics• Hard real-time process automation requirements• i.e., 250 ms real-time cycles

• System acquires values representing plant’s current state, tracks material flow, calculates new settings for the rolls & devices, & submits new settings back to plant

Key Software Solution Characteristics

•Affordable, flexible, & COTS• Product-line architecture• Design guided by patterns & frameworks

•Affordable, flexible, & COTS• Product-line architecture• Design guided by patterns & frameworks

• Windows NT/2000• Real-time CORBA (ACE+TAO)

www.siroll.de

Page 21: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

21

Example:

Applying COTS to Real-time Image Processing

Goals• Examine glass bottles for defects in real-time

System Characteristics• Process 20 bottles per sec• i.e., ~50 msec per bottle

• Networked configuration

• ~10 cameras

Key Software Solution Characteristics

•Affordable, flexible, & COTS• Embedded Linux (Lem)• Compact PCI bus + Celeron processors

•Affordable, flexible, & COTS• Embedded Linux (Lem)• Compact PCI bus + Celeron processors

• Remote booted by DHCP/TFTP• Real-time CORBA (ACE+TAO)

www.krones.com

Page 22: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

22

Motivations•Leverage hardware/software advances

•Simplify program structure•Increase performance•Improve response-time

Key Opportunities & Challenges in Concurrent Applications

Accidental Complexities•Low-level APIs•Poor debugging tools

Inherent Complexities•Scheduling•Synchronization•Deadlocks

Page 23: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

23

Key Opportunities & Challenges in Networked & Distributed Applications

Motivations• Collaboration• Performance• Reliability & availability• Scalability & portability• Extensibility• Cost effectiveness

Accidental Complexities•Algorithmic decomposition•Continuous re-invention & re-discovery of core concepts & components

Inherent Complexities•Latency•Reliability•Load balancing•Causal ordering•Security & information assurance

Page 24: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

24

•Present solutions to common software problems arising within a certain context

Overview of Patterns

•Capture recurring structures & dynamics among software participants to facilitate reuse of successful designs

The Proxy Pattern

1 1Proxy

service

Service

service

AbstractService

service

Client

•Help resolve key software design forces

•Flexibility•Extensibility•Dependability•Predictability•Scalability•Efficiency

•Generally codify expert knowledge of design strategies, constraints & “best practices”

Page 25: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

25

Overview of Pattern Languages

Benefits of Pattern Languages• Define a vocabulary for talking about software

development problems• Provide a process for the orderly resolution of

these problems• Help to generate & reuse software architectures

Motivation•Individual patterns & pattern catalogs are insufficient

•Software modeling methods & tools largely just illustrate how – not why – systems are designed

Page 26: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

26

Taxonomy of Patterns & Idioms

Type Description Examples

Idioms Restricted to a particular language, system, or tool

Scoped locking

Design patterns

Capture the static & dynamic roles & relationships in solutions that occur repeatedly

Active Object, Bridge, Proxy, Wrapper Façade, & Visitor

Architectural patterns

Express a fundamental structural organization for software systems that provide a set of predefined subsystems, specify their relationships, & include the rules and guidelines for organizing the relationships between them

Half-Sync/Half-Async, Layers, Proactor, Publisher-Subscriber, & Reactor

Optimization principle patterns

Document rules for avoiding common design & implementation mistakes that degrade performance

Optimize for common case, pass information between layers

Page 27: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

27

Example: Boeing Bold StrokeNav Sensors

WeaponManagement

Data LinksMissionComputer

VehicleMgmt

Weapons

• Avionics mission computing product-line architecture for Boeing military aircraft, e.g., F-18 E/F, 15E, Harrier, UCAV

• DRE system with 100+ developers, 3,000+ software components, 3-5 million lines of C++ code

• Based on COTS hardware, networks, operating systems, & middleware

• Used as Open Experimention Platform (OEP) for DARPA IXO PCES, MoBIES, SEC, MICA programs

Bold Stroke Architecture

Hardware (CPU, Memory, I/O)Hardware (CPU, Memory, I/O)

Networking InterfacesNetworking Interfaces

Operating SystemOperating System

Middleware InfrastructureMiddleware Infrastructure

Mission Computing ServicesMission Computing Services

Radar

Page 28: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

28

Hardware (CPU, Memory, I/O)Hardware (CPU, Memory, I/O)

Networking InterfacesNetworking Interfaces

Operating SystemOperating System

Middleware InfrastructureMiddleware Infrastructure

Mission Computing ServicesMission Computing Services

Example: Boeing Bold Stroke

COTS & Standards-based Middleware Infrastructure, OS, Network, & Hardware Platform• Real-time CORBA middleware services• VxWorks operating system• VME, 1553, & Link16• PowerPC

Page 29: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

29

Example: Boeing Bold StrokeReusable Object-Oriented Application Domain-specific Middleware Framework • Configurable to variable infrastructure configurations

• Supports systematic reuse of mission computing functionality

Hardware (CPU, Memory, I/O)Hardware (CPU, Memory, I/O)

Networking InterfacesNetworking Interfaces

Operating SystemOperating System

Middleware InfrastructureMiddleware Infrastructure

Mission Computing ServicesMission Computing Services

Page 30: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

30

Example: Boeing Bold Stroke

Product Line Component Model• Configurable for product-specific functionality

& execution environment• Single component development policies• Standard component packaging mechanisms

Hardware (CPU, Memory, I/O)Hardware (CPU, Memory, I/O)

Networking InterfacesNetworking Interfaces

Operating SystemOperating System

Middleware InfrastructureMiddleware Infrastructure

Mission Computing ServicesMission Computing Services

Page 31: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

31

Hardware (CPU, Memory, I/O)Hardware (CPU, Memory, I/O)

Networking InterfacesNetworking Interfaces

Operating SystemOperating System

Middleware InfrastructureMiddleware Infrastructure

Mission Computing ServicesMission Computing Services

Example: Boeing Bold Stroke

Component Integration Model• Configurable for product-specific component assembly & deployment environments

• Model-based component integration policies

Avionics Interfaces

Operator

Real World Model

Infrastructure Services

Page 32: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

32

Legacy Avionics Architectures

Board 1

VME

1553

1: Sensors generate data

Board 2

2: I/O via interrupts

3: Sensor proxies process data & pass to missions functions

4: Mission functions perform avionics operations

Key System Characteristics•Hard & soft real-time deadlines

•~20-40 Hz•Low latency & jitter between boards•~100 usecs

•Periodic & aperiodic processing•Complex dependencies•Continuous platform upgrades

Avionics Mission Computing Functions•Weapons targeting systems (WTS)

•Airframe & navigation (Nav)

•Sensor control (GPS, IFF, FLIR)

•Heads-up display (HUD)

•Auto-pilot (AP)

Page 33: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

33

Legacy Avionics Architectures

Board 1

VME

1553

1: Sensors generate data

Board 2

2: I/O via interrupts

3: Sensor proxies process data & pass to missions functions

4: Mission functions perform avionics operations

AirFrame

AP

Nav WTS

GPS IFF

FLIR

Cyclic ExecLimitations with Legacy Avionics

Architectures•Stovepiped•Proprietary•Expensive•Vulnerable•Tightly coupled•Hard to schedule•Brittle & non-adaptive

Key System Characteristics•Hard & soft real-time deadlines

•~20-40 Hz•Low latency & jitter between boards•~100 usecs

•Periodic & aperiodic processing•Complex dependencies•Continuous platform upgrades

Page 34: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

34

Decoupling Avionics Components

Context Problems Solution

• I/O driven DRE application

• Complex dependencies

• Real-time constraints

• Tightly coupled components

• Hard to schedule

• Expensive to evolve

• Apply the Publisher-Subscriber architectural pattern to distribute periodic, I/O-drivendata from a single point of source to a collection of consumers

Event*

Subscriber

consume

creates receives

Event Channel

attachPublisher detachPublisherattachSubscriberdetachSubscriberpushEvent

Filter

filterEvent

Publisher

produce

Structure

attachSubscriber

produce

pushEventevent

eventpushEvent

consume

detachSubscriber

: Event

: Subscriber: Event Channel: Publisher

Dynamics

Page 35: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

35

Applying the Publisher-Subscriber Pattern to Bold Stroke

Board 1

VME

1553

1: Sensors generate data

Board 2

2: I/O via interrupts

4: Event Channel pushes events to subscribers(s)

5: Subscribers perform avionics operations

GPS IFF FLIR

HUD

Nav

WTSAir

Frame

Publishers

Subscribers

push(event)

push(event)

Event Channel

3: Sensor publishers push events to event channel

Considerations for implementing the Publisher-Subscriber pattern for mission computing applications include:• Event notification model

•Push control vs. pull data interactions• Scheduling & synchronization strategies•e.g., priority-based dispatching & preemption

• Event dependency management•e.g.,filtering & correlation mechanisms

Bold Stroke uses the Publisher-Subscriber pattern to decouple sensor processing from mission computing operations• Anonymous publisher & subscriber relationships

• Group communication

• Asynchrony

Page 36: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

36

Ensuring Platform-neutral & Network-transparent Communication

Context Problems Solution

• Mission computing requires remote IPC

• Stringent DRE requirements

• Applications need capabilities to:•Support remote communication•Provide location transparency•Handle faults•Manage end-to-end QoS•Encapsulate low-level system details

• Apply the Broker architectural pattern to provide platform-neutral communication between mission computing boards

message exchange

message exchange

*

marshalunmarhalreceive_resultservice_p

Client Proxy

calls*

*

call_service_pstart_task

Client

1

marshalunmarshaldispatchreceive_request

Server Proxy

calls*

start_upmain_loopservice_i

Server

1

1

main_loopsrv_registrationsrv_lookupxmit_messagemanage_QoS

Broker1

Structure

Page 37: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

37

Ensuring Platform-neutral & Network-transparent Communication

operation (params)connect

send_requestmarshal

unmarshal

dispatchoperation (params)

resultmarshalreceive_repl

yunmarshal

result

start_upregister_serviceassigned port

Dynamics

: Broker: Client Proxy : Server Proxy: Client : Server

Context Problems Solution

• Mission computing requires remote IPC

• Stringent DRE requirements

• Applications need capabilities to:•Support remote communication•Provide location transparency•Handle faults•Manage end-to-end QoS•Encapsulate low-level system details

• Apply the Broker architectural pattern to provide platform-neutral communication between mission computing boards

Page 38: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

38

Applying the Broker Pattern to Bold Stroke

Board 1

VME

1553

1: Sensors generate data

Board 2

2: I/O via interrupts

5: Event Channel pushes events to subscribers(s)

6: Subscribers perform avionics operations

GPS IFF FLIR

HUD Nav WTS Air Frame

Publishers

Subscribers

push(event)

push(event)

Event Channel

4: Sensor publishers push events to event channel

Bold Stroke uses the Broker pattern to shield distributed applications from environment heterogeneity, e.g., • Programming languages• Operating systems• Networking protocols• Hardware

3: Broker handles I/O via upcalls

Broker

A key consideration for implementing the Broker pattern for mission computing applications is QoS support

• e.g., latency, jitter, priority preservation, dependability, security, etc.

CaveatThese patterns are very useful, but

having to implement them from scratch is tedious & error-prone!!!

Page 39: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

39

Software Design Abstractions for Concurrent & Networked Applications

Problem• Distributed app & middleware functionality is subject to change since it’s often reused in unforeseen contexts, e.g., •Accessed from different clients

•Run on different platforms•Configured into different run-time contexts

MIDDLEWARE

Solution•Don‘t structure distributed applications & middleware as a monolithic spagetti

• Instead, decompose them into modular classes, frameworks, & components

Solution•Don‘t structure distributed applications & middleware as a monolithic spagetti

• Instead, decompose them into modular classes, frameworks, & components

Page 40: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

40

Overview of Frameworks

Framework Characteristics

Application-specific functionality

•Frameworks exhibit “inversion of control” at runtime via callbacks

Networking Database

GUI

•Frameworks provide integrated domain-specific structures & functionality

Mission Computing E-commerce

ScientificVisualization

•Frameworks are “semi-complete” applications

Page 41: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

41

Comparing Class Libraries, Frameworks, & Components

Class Libraries

Frameworks

Macro-levelMeso-levelMicro-level

Borrow caller’s thread

Inversion of control

Borrow caller’s thread

Domain-specific or Domain-independent

Domain-specific

Domain-independent

Stand-alone composition

entities

“Semi-complete”

applications

Stand-alone language entities

Components

Class Library Architecture

ADTs

Strings

LocksIPC

Math

LOCAL INVOCATIONSAPPLICATION-

SPECIFICFUNCTIONALITY

EVENTLOOP

GLUECODE

Files

GUI

A class is a unit of abstraction & implementation in an OO

programming language

Framework Architecture

ADTs

Locks

Strings

Files

INVOKES

A framework is an integrated set of classes that collaborate to produce a reusable architecture for a family of applications

Reactor

GUI

DATABASE

NETWORKING

APPLICATION-SPECIFIC FUNCTIONALITY CALLBACKS

Middleware Bus

Component Architecture

A component is an encapsulation unit with one or more interfaces that provide

clients with access to its services

Naming

LockingLogging

Events

Page 42: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

42

Using Frameworks Effectively

Observations•Frameworks are powerful, but hard to develop & use effectively by application developers•It’s often better to use & customize COTS frameworks than to develop in-house frameworks

•Components are easier for application developers to use, but aren’t as powerful or flexible as frameworks

Successful projects are therefore often

organized using the “funnel” model

Page 43: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

43

Overview of the ACE Frameworks

Features•Open-source•6+ integrated frameworks

•250,000+ lines of C++•40+ person-years of effort

•Ported to Windows, UNIX, & real-time operating systems

• e.g., VxWorks, pSoS, LynxOS, Chorus, QNX

•Large user community

www.cs.wustl.edu/~schmidt/ACE.html

Acceptor Connector Component

Configurator

Stream

Reactor Proactor

Task

Application-specific

functionality

Local AreaNetwork

NYSE

NASDAQ

Page 44: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

44

The Layered Architecture of ACEFeatures•Open-source•250,000+ lines of C++

•40+ person-years of effort

•Ported to Win32, UNIX, & RTOSs

• e.g., VxWorks, pSoS, LynxOS, Chorus, QNX

•Large open-source user community• www.cs.wustl.edu/~schmidt/ACE-users.html

•Commercial support by Riverace• www.riverace.com/

www.cs.wustl.edu/~schmidt/ACE.html

Page 45: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

45

Service Access & Control Event Handling

Concurrency

Key Capabilities Provided by ACE

Synchronization

Page 46: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

46

Pattern Benefits

• Preserve crucial design information used by applications & middleware frameworks & components

• Facilitate reuse of proven software designs & architectures

• Guide design choices for application developers

The POSA2 Pattern Language

Page 47: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

47

POSA2 Pattern AbstractsService Access & Configuration Patterns

The Wrapper Facade design pattern encapsulates the functions and data provided by existing non-object-oriented APIs within more concise, robust, portable, maintainable, and cohesive object-oriented class interfaces.

The Component Configurator design pattern allows an application to link and unlink its component implementations at run-time without having to modify, recompile, or statically relink the application. Component Configurator further supports the reconfiguration of components into different application processes without having to shut down and re-start running processes.

The Interceptor architectural pattern allows services to be added transparently to a framework and triggered automatically when certain events occur.

The Extension Interface design pattern allows multiple interfaces to be exported by a component, to prevent bloating of interfaces and breaking of client code when developers extend or modify the functionality of the component.

Event Handling Patterns

The Reactor architectural pattern allows event-driven applications to demultiplex and dispatch service requests that are delivered to an application from one or more clients.

The Proactor architectural pattern allows event-driven applications to efficiently demultiplex and dispatch service requests triggered by the completion of asynchronous operations, to achieve the performance benefits of concurrency without incurring certain of its liabilities.

The Asynchronous Completion Token design pattern allows an application to demultiplex and process efficiently the responses of asynchronous operations it invokes on services.

The Acceptor-Connector design pattern decouples the connection and initialization of cooperating peer services in a networked system from the processing performed by the peer services after they are connected and initialized.

Page 48: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

48

POSA2 Pattern Abstracts (cont’d)Synchronization Patterns

The Scoped Locking C++ idiom ensures that a lock is acquired when control enters a scope and released automatically when control leaves the scope, regardless of the return path from the scope.

The Strategized Locking design pattern parameterizes synchronization mechanisms that protect a component’s critical sections from concurrent access.

The Thread-Safe Interface design pattern minimizes locking overhead and ensures that intra-component method calls do not incur ‘self-deadlock’ by trying to reacquire a lock that is held by the component already.

The Double-Checked Locking Optimization design pattern reduces contention and synchronization overhead whenever critical sections of code must acquire locks in a thread-safe manner just once during program execution.

Concurrency Patterns

The Active Object design pattern decouples method execution from method invocation to enhance concurrency and simplify synchronized access to objects that reside in their own threads of control.

The Monitor Object design pattern synchronizes concurrent method execution to ensure that only one method at a time runs within an object. It also allows an object’s methods to cooperatively schedule their execution sequences.

The Half-Sync/Half-Async architectural pattern decouples asynchronous and synchronous service processing in concurrent systems, to simplify programming without unduly reducing performance. The pattern introduces two intercommunicating layers, one for asynchronous and one for synchronous service processing.

The Leader/Followers architectural pattern provides an efficient concurrency model where multiple threads take turns sharing a set of event sources in order to detect, demultiplex, dispatch, and process service requests that occur on the event sources.

The Thread-Specific Storage design pattern allows multiple threads to use one ‘logically global’ access point to retrieve an object that is local to a thread, without incurring locking overhead on each object access.

Page 49: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

49

Implementing the Broker Pattern for Bold Stroke Avionics

• CORBA is a distribution middleware standard

• Real-time CORBA adds QoS to classic CORBA to control:

www.omg.org

3. Memory Resources

•These capabilities address some (but by no means all) important DRE application development & QoS-enforcement challenges

2. Communication Resources

ProtocolProperties

Explicit Binding

Client Propagation & Server Declared Priority Models

Portable Priorities

Thread Pools

Static Scheduling Service

StandardSynchonizers 1. Processor Resources

Request Buffering

Page 50: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

50

Example of Applying Patterns & Frameworks to Middleware:

Real-time CORBA & The ACE ORB (TAO)TAO Features•Open-source•500+ classes & 500,000+ lines of C++

•ACE/patterns-based•30+ person-years of effort

•Ported to UNIX, Win32, MVS, & many RT & embedded OSs

• e.g., VxWorks, LynxOS, Chorus, QNX

www.cs.wustl.edu/~schmidt/TAO.html

•Large open-source user community•www.cs.wustl.edu/~schmidt/TAO-users.html

•Commercially supported• www.theaceorb.com• www.prismtechnologies.com

Protocol Properties Explicit Binding

Thread Pools

Scheduling Service

Standard Synchronizers

Portable Priorities

End-to-end Priority Propagation

Page 51: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

51

Key Patterns Used in TAO

www.cs.wustl.edu/~schmidt/PDF/ORB-patterns.pdf

• Wrapper facades enhance portability

• Proxies & adapters simplify client & server applications, respectively

• Component Configurator dynamically configures Factories

• Factories produce Strategies

• Strategies implement interchangeable policies

• Concurrency strategies use Reactor & Leader/Followers

• Acceptor-Connector decouples connection management from request processing

• Managers optimize request demultiplexing

Page 52: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

52

Enhancing ORB Flexibility w/the Strategy Pattern

Context Problem Solution

• Multi-domain resuable middleware framework

• Flexible ORBs must support multiple event & request demuxing, scheduling, (de)marshaling, connection mgmt, request transfer, & concurrency policies

• Apply the Strategy pattern to factory out similarity amongst alternative ORB algorithms & policies

Hook for the concurrency strategy

Hook for the request demuxing strategy

Hook for marshaling strategy

Hook for the connection management strategy

Hook for the underlying transport strategy

Hook for the event demuxing strategy

Page 53: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

53

Consolidating Strategies with the Abstract Factory Pattern

Context Problem Solution

• A heavily strategized framework or application

• Aggressive use of Strategy pattern creates a configuration nightmare

• Managing many individual strategies is hard

• It’s hard to ensure that groups of semantically compatible strategies are configured

• Apply the Abstract Factory pattern to consolidate multiple ORB strategies into semantically compatible configurations

Concrete factories create groups of strategies

Page 54: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

54

Dynamically Configuring Factories w/the Component Configurator Pattern

Context Problem Solution

• Resource constrained & highly dynamic environments

• Prematurely commiting to a particular ORB configuration is inflexible & inefficient•Certain decisions can’t be made until runtime

•Forcing users to pay for components that don’t use is undesirable

• Apply the Component Configurator pattern to assemble the desired ORB factories (& thus strategies) dynamically

• ORB strategies are decoupled from when the strategy implementations are configured into an ORB

• This pattern can reduce the memory footprint of an ORB

Page 55: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

55

ACE Frameworks Used in TAO

• Reactor drives the ORB event loop

• Implements the Reactor & Leader/Followers patterns

• Acceptor-Connector decouples passive/active connection roles from GIOP request processing

• Implements the Acceptor-Connector & Strategy patterns

• Service Configurator dynamically configures ORB strategies

• Implements the Component Configurator & Abstract Factory patterns

www.cs.wustl.edu/~schmidt/PDF/ICSE-03.pdf

Page 56: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

56

Summary of Pattern, Framework, & Middleware Synergies

The technologies codify expertise of experienced researchers & developers

• Patterns codify expertise in the form of reusable architecture design themes & styles, which can be reused event when algorithms, components implementations, or frameworks cannot

• Frameworks codify expertise in the form of reusable algorithms, component implementations, & extensible architectures

Application-specific functionality

Acceptor Connecto

rComponentConfigurator

Stream

Reactor

Proactor

Task

• Middleware codifies expertise in the form of standard interfaces & components that provide applications with a simpler façade to access the powerful (& complex) capabilities of frameworks

There are now powerful feedback loops advancing these technologies

Page 57: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

57

Tutorial Example:

Electronic Medical Imaging SystemsGoal•Route, manage, & manipulate electronic medical images robustly, efficiently, & securely thoughout a distributed health care environment

Modalitiese.g., MRI, CT, CR,

Ultrasound, etc.

Modalitiese.g., MRI, CT, CR,

Ultrasound, etc.

Page 58: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

58

Tutorial Example:

Electronic Medical Imaging Systems

System Characteristics •Large volume of “blob” data

•e.g.,10 to 40 Mbps•“Lossy” compression isn’t viable due to liability concerns

•Diverse QoS requirements, e.g.,• Sync & async communication• Event- & method-based invocation

• Streaming communication• Prioritization of requests & streams

• Distributed resource management

Modalitiese.g., MRI, CT, CR,

Ultrasound, etc.

Modalitiese.g., MRI, CT, CR,

Ultrasound, etc.

Page 59: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

59

Tutorial Example:

Electronic Medical Imaging Systems

Modalitiese.g., MRI, CT, CR,

Ultrasound, etc.

Modalitiese.g., MRI, CT, CR,

Ultrasound, etc.

Key Software Solution Characteristics (e.g., www.syngo.com)

•Affordable, flexible, & COTS•Product-line architecture•Design guided by patterns & frameworks

•Affordable, flexible, & COTS•Product-line architecture•Design guided by patterns & frameworks

•General-purpose & embedded OS platforms

•Middleware technology agnostic

Page 60: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

60

8. New

9. Return Ref

7.New

1. Deploy

3. BindFactory

Image Xfer Interface

Image Xfer Interface

ConfigurationDatabase

ConfigurationConfiguration

ContainerContainer

Image Acquisition Scenario

Image XferComponent

Executor

Image XferComponent

Executor

2. Enter info

6. Intercept & delegate

Xfer ProxyXfer Proxy

Factory ProxyFactory Proxy

10. Invoke get_image() call

11. Query Config.

12. Check Authorization

5. Find Image

Diagnostic & Clinical Workstations

13. Activate

Factory/FinderFactory/FinderSecurity ServiceSecurity Service

NamingServiceNamingService

4. Find Factory

RadiologyClient

RadiologyClient

14. Delegate

Key Tasks1.Image

location & routing

2.Image delivery

ImageDatabase

Page 61: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

61

Image Xfer Interface

Image Xfer Interface

ConfigurationDatabase ConfigurationConfiguration

ContainerContainer

Image XferComponent

Servant

Image XferComponent

Servant

Xfer ProxyXfer Proxy

Factory ProxyFactory Proxy

ImageDatabase

Factory/FinderFactory/FinderSecurity ServiceSecurity Service

NamingServiceNamingService

RadiologyClient

RadiologyClient

Applying Patterns to Resolve Key Distributed System Design Challenges

Patterns help resolve the following common design challenges: •Decoupling suppliers & consumers•Locating & creating components scalably

•Extending components transparently

•Minimizing resource utilization•Enhancing server (re)configurability

•Decoupling suppliers & consumers•Locating & creating components scalably

•Extending components transparently

•Minimizing resource utilization•Enhancing server (re)configurability

•Separating concerns between tiers•Improving type-safety & performance •Enabling client extensibility•Ensuring platform-neutral & network-transparent OO communication

•Supporting async communication•Supporting OO async communication

•Separating concerns between tiers•Improving type-safety & performance •Enabling client extensibility•Ensuring platform-neutral & network-transparent OO communication

•Supporting async communication•Supporting OO async communication

Proxy

Broker

Active Object

Publisher-Subscriber

ComponentConfigurator

ExtensionInterface

Factory/Finder

AsyncForwarder/Receiver

Layers

Interceptor

Activator

Page 62: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

62

Solution•Apply the Layers pattern (P1) to create a multi-tier architecture that separates concerns between groups of tasks occurring at distinct layers in the distributed system

Solution•Apply the Layers pattern (P1) to create a multi-tier architecture that separates concerns between groups of tasks occurring at distinct layers in the distributed system

Separating Concerns Between TiersContext• Distributed systems are now common due to the advent of • The global Internet • Ubiquitous mobile & embedded devices

Problem• It’s hard to build COTS-based distributed systems is because many capabilities must be provided to meet application requirements end-to-end

Services in the middle tier participate in various types of tasks, e.g.,

•Workflow of integrated “business” processes

•Connect to databases & other backend systems for data storage & access

Database Tier• e.g., persistent data

DBServer

DBServer

Middle Tier• e.g., common business logic

comp

comp

Application

Server

Presentation Tier• e.g., thin client displays

Client Client

Page 63: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

63

Applying the Layers Pattern to Image Acquisition

Image servers are middle tier entities that:•Provide server-side functionality

•e.g., they are responsible for scalable concurrency & networking•Can run in their own address space•Are integrated into containers that hide low-level OS platform details

Image servers are middle tier entities that:•Provide server-side functionality

•e.g., they are responsible for scalable concurrency & networking•Can run in their own address space•Are integrated into containers that hide low-level OS platform details

ImageDatabase

PatientDatabase

Database Tier•e.g., persistent image data

Middle Tier•e.g., image routing, security, & image transfer logic

comp

comp

Image

Servers

Presentation Tier•e.g., radiology clients

DiagnosticWorkstations

ClinicalWorkstations

Diagnostic & clinical workstations are presentation tier entities that:•Typically represent sophisticated GUI elements

•Share the same address space with their clients• Their clients are containers that provide all the resources

•Exchange messages with the middle tier components

Page 64: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

64

Pros & Cons of the Layers Pattern

This pattern has four benefits:•Reuse of layers

• If an individual layer embodies a well-defined abstraction & has a well-defined & documented interface, the layer can be reused in multiple contexts

•Support for standardization• Clearly-defined & commonly-accepted levels of abstraction enable the development of standardized tasks & interfaces

•Dependencies are localized• Standardized interfaces between layers usually confine the effect of code changes to the layer that is changed

•Exchangeability• Individual layer implementations can be replaced by semantically-equivalent implementations without undue effort

This pattern also has liabilities:•Cascades of changing behavior

• If layer interfaces & semantics aren’t abstracted properly then changes can ripple when behavior of a layer is modified

•Higher overhead• A layered architecture can be less efficient than a monolithic architecture

•Unnecessary work• If some services performed by lower layers perform excessive or duplicate work not actually required by the higher layer, performance can suffer

•Difficulty of establishing the correct granularity of layers• It’s important to avoid too many & too few layers

Page 65: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

65

Overview of Distributed Object Computing Communication Mechanisms

Solution• DOC middleware provides multiple types of communication mechanisms:

•Collocated client/server (i.e., native function call)•Synchronous & asynchronous RPC/IPC•Group communication & events•Data streaming

Problem•A single communication mechanism does not fit all uses!

ContextIn multi-tier systems both the tiers & the components within the tiers must be connected via communication mechanisms

Next, we’ll explore various patterns that applications can apply to leverage these communication mechanisms

Next, we’ll explore various patterns that applications can apply to leverage these communication mechanisms

Page 66: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

66

Improving Type-safety & Performance (1/2)

Context• The configuration of components in distributed systems is often subject to change as requirements evolve

Problems• Low-level message passing (e.g., using sockets) is error-prone & fraught with accidental complexity

• Remote components should look like local components from an application perspective

• i.e., ideally clients & servers should be oblivious to communication mechanisms & locations

Page 67: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

67

Improving Type-safety & Performance (2/2)

• A Service implements the object, which is not accessible directly

• A Proxy represents the Service & ensures the correct access to it

• Proxy offers same interface as Service

• Clients use the Proxy to access the Service

Proxy

service

Client

Service

service1 1

AbstractService

serviceSolutionApply the Proxy design pattern (P1) to provide an OO surrogate through which clients can access remote objects

SolutionApply the Proxy design pattern (P1) to provide an OO surrogate through which clients can access remote objects

: Service: Proxy: Clientservice

service

pre-processing: e.g.,marshaling

post-processing: e.g., unmarshaling

Page 68: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

68

Applying the Proxy Pattern to Image Acquisition

Proxy

get_image()

Client

Sync Image Xfer

get_image()1 1

Image Xfer

get_image()We can apply the Proxy pattern to provide a strongly-typed interface to initiate & coordinate the downloading of images from an image database

Proxies that are generated automatically by middleware can be optimized to be much more efficient than manual message passing•e.g., improved memory management, data copying, & compiled marshaling/demarshaling

Proxies that are generated automatically by middleware can be optimized to be much more efficient than manual message passing•e.g., improved memory management, data copying, & compiled marshaling/demarshaling

Image Xfer Service

Image Xfer ServiceXfer ProxyXfer Proxy

ImageDatabase

RadiologyClient

RadiologyClient

Invoke get_image() call

Page 69: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

69

Pros & Cons of the Proxy Pattern

This pattern provides three benefits:•Decoupling clients from the location of server components• Clients are not affected by migration of servers or changes in the networking infrastructure since location information & addressing functionality is managed by a proxy

•Separation of housekeeping & functionality• A proxy relieves clients from burdens that do not inherently belong to the task the client performs

•Potential for time & space optimizations• Proxy implementations can be loaded “on-demand” & can also be used to cache values to avoid redundant remote calls

• Proxies can also be optimized to improve both type-safety & performance

This pattern has two liabilities:•Potential overkill via sophisticated strategies• If proxies include overly sophisticated functionality, such as caching or replica management, they many introduce overhead that defeats their intended purpose

•Higher overhead due to indirection• Proxies introduce an additional layer of indirection that can be excessive if the proxy implementation is inefficient

Page 70: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

70

Enabling Client Extensibility (1/2)

Context• Object models define how components import & export functionality•e.g., UML class diagrams specify well-defined OO interfaces

Class Xoperation1()operation2()operation3()operationn()

Problem• Many object models assign a single interface to each component

• This design makes it hard to evolve components without either1. Breaking existing client

interfaces2. Bloating client interfaces

operation()Object : Class X

: Client

Page 71: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

71

Enabling Client Extensibility (2/2)Solution• Apply the Extension Interface design pattern (P2), which allows multiple interfaces to be exported by a component, to prevent breaking of client code & bloating of interfaces when developers extend or modify component functionality

Solution• Apply the Extension Interface design pattern (P2), which allows multiple interfaces to be exported by a component, to prevent breaking of client code & bloating of interfaces when developers extend or modify component functionality

createComponent

Factory

*

*

CreateInstance

createComponent

Componentnew

*1

queryInterface

Root

Implemented by

1+

<<extends>>

Ask for a reference to an interface

Call an operation on an interface

initialize

uninititialize

ServerqueryInterface

service_i

ExtensionInterface i

callService

Client

queryInterface()

: Clientoperation()

Page 72: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

72

Extension Interface Pattern Dynamics

: Client

Start_client

: Factory

createInstance(Ext.Intf. 1)new

Ref. To Extension1

create

create

service_1

queryInterface(Extension Interface 2)

Ref. To Extension2

service2

Note how each extension interface can serve as a “factory” to return object reference to other extension interfaces supported by a component

Note how each extension interface can serve as a “factory” to return object reference to other extension interfaces supported by a component

: Component : Extension 1 : Extension 2

service_2

A common use of the Extension Interface pattern is to support component versioning• Off-loads versioning protocol to client…

Page 73: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

73

Pros & Cons of the Extension Interface Pattern

This pattern has five benefits:•Separation of concerns

• Interfaces are strictly decoupled from implementations

•Exchangeability of components• Component implementations can evolve independently from clients that access them

•Extensibility through interfaces• Clients only access components via their interfaces, which reduces coupling to representation & implementation details

•Prevention of interface bloating• Interfaces need not contain all possible methods, just the ones associated with a particular capability

•No subclassing required• Delegation—rather than inheritance—is used to customize components

This pattern also has liabilities:•Higher overhead due to indirection• Clients must incur the overhead of several round-trips to obtain the appropriate object reference from a server component

•Complexity & cost for development & deployment• This pattern off-loads the responsibility for determining the appropriate interface from the component designer to the client applications

Page 74: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

74

Ensuring Platform-neutral & Network-transparent OO Communication (1/2)

Problem• A middleware architecture needs to:

•Support remote method invocation•Provide location transparency•Detect & recover from faults•Allow the addition, exchange, or remove of services dynamically

•Hide system details from developers

Context•The Proxy pattern is insufficient since it doesn’t address how•Remote components are located•Connections are established•Messages are exchanged across a network

•etc.

Proxy

service

Client

Service

service1 1

AbstractService

service

Page 75: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

75

Ensuring Platform-neutral & Network-transparent OO Communication (2/2)

Solution•Apply the Broker architectural pattern (P1) to provide OO platform-neutral communication between networked client & server components

Solution•Apply the Broker architectural pattern (P1) to provide OO platform-neutral communication between networked client & server components

message exchange

message exchange

*

marshalunmarhalreceive_resultservice_p

Client Proxy

calls*

*

call_service_pstart_task

Client

1

marshalunmarshaldispatchreceive_request

Server Proxy

calls*

start_upmain_loopservice_i

Server

1

1

main_loopsrv_registrationsrv_lookuptransmit_message

Broker1

Page 76: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

76

Broker Pattern Dynamics

method (proxy) locate_server

server port

send_request

marshal

unmarshal

dispatchmethod (impl.)

result

marshalreceive_reply

unmarshal

result

start_upregister_service

: Broker: Client Proxy : Server Proxy: Client : Server

assigned port

Broker middleware generates the necessary client & server proxies from higher level interface definitions

Proxy Proxy GeneratorGenerator

ProxyProxy

CodeCode InterfaceInterface

Specif.Specif.

Page 77: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

77

Applying the Broker Pattern to Image Acquisition

• Common Broker pattern

implementations •CORBA•COM+•Java RMI•Med-specific Comm (MSC)

• Brokers define interfaces…•… not implementations

• Brokers simplify development of distributed applications by automating

•Object location•Connection management•Memory management•Parameter (de)marshaling•Event & request demuxing•Error handling•Object/server activation•Concurrency

•Brokers help shield distributed applications from environment heterogeneity•e.g., programming languages, operating systems, networking protocols, hardware, etc.

Container

OS & Protocols

Communication Infrastructure

OS & Protocols

ClientProxy

Server Proxy

Object Adapter

Image Xfer Component

Client CommonServices

BrokerInterface

Page 78: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

78

Pros & Cons of the Broker PatternThis pattern has five benefits:•Portability enhancements

• A broker hides OS & network system details from clients and servers by using indirection & abstraction layers, such as APIs, proxies, adapters, & bridges

•Interoperability with other brokers• Different brokers may interoperate if they understand a common protocol for exchanging messages

•Reusability of services• When building new applications, brokers enable application functionality to reuse existing services

•Location transparency• A broker is responsible for locating servers, so clients need not know where servers are located

•Changeability & extensibility of components• If server implementations change without affecting interfaces clients should not be affected

This pattern also has liabilities:

•Higher overhead• Applications using brokers may be slower than applications written manually

•Potentially less reliable• Compared with non-distributed software applications, distributed broker systems may incur lower fault tolerance

•Testing & debugging may be harder• Testing & debugging of distributed systems is tedious because of all the components involved

Page 79: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

79

Supporting Async Communication (1/2)

Context• Some clients want to send requests, continue their work, & receive the results at some later point in time

Problem•Broker implementations based on conventional RPC semantics often just support blocking operations

• i.e., clients must wait until twoway invocations return

•Unfortunately, this design can reduce scalability & complicate certain use-cases

Page 80: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

80

Solution•Apply the Async Forwarder/Receiver (P1) design pattern to allow asynchronous communication between clients & servers

Solution•Apply the Async Forwarder/Receiver (P1) design pattern to allow asynchronous communication between clients & servers

Local Queue

storeforwardremove

Message <<forward>>

Client Message API<<send>>

Remote Queue

storeforwardremove<<exec>>

MessageProcessor Message API<<recv>>

Supporting Async Communication (1/2)

Introduce intermediary queue(s) between clients & servers:

• A queue is used to store messages

• A queue can cooperate with other queues to route messages

• Messages are sent from sender to receiver

• A client sends a message, which is queued & then forwarded to a message processor on a server that receives & executes them

• A Message API is provided for clients & servers to send/receive messages

Page 81: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

81

Async Forwarder/Receiver Pattern Dynamics

: Client

: Messagecreate

storeMessage

forwardMessage

: MessageProcessor

createreceive

receive

Message

Message

exec

send Message

: Message API

: LocalQueue

: RemoteQueue

: Message API

Reply

store

forwardReply

recv Reply

send

Reply

recv

Otherprocessing

Page 82: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

82

Applying the Async Forwarder/Receiver Pattern to Image Acquisition

We can apply the Async Forwarder/Receiver pattern to•Queue up image request messages remotely without blocking the diagnostic/clinical workstation clients

•Execute the requests at a later point & return the results to the client

Local Queue

storeforwardremove

Message <<route>>

RadiologyClient Message API

<<send>>

Remote Queue

storeforwardremove<<exec>>

Message API<<recv>>

Image ServerMessage

Processor

Image Xfer Service

Image Xfer Service

ImageDatabase

RadiologyClient

RadiologyClient

This design also enables other, more advanced capabilities, e.g.,•Multi-hop store & forward persistence•QoS-driven routing, where requests can be delivered to the “best” image database depending on context

This design also enables other, more advanced capabilities, e.g.,•Multi-hop store & forward persistence•QoS-driven routing, where requests can be delivered to the “best” image database depending on context

Page 83: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

83

This pattern provides three benefits:•Enhances concurrency by transparently leveraging available parallelism• Messages can be executed remotely on servers while clients perform other processing

•Simplifies synchronized access to a shared object that resides in its own thread of control• Since messages are processed serially by a message processor target objects often need not be concerned with synchronization mechanisms

•Message execution order can differ from message invocation order• This allows reprioritizing of messages to enhance quality of service

• Messages can be “batched” and sent wholesale to enhance throughout

This pattern also has some liabilities:

•Message execution order can differ from message invocation order• As a result, clients must be careful not to rely on ordering dependencies

•Lack of type-safety• Clients & servers are responsible for formatting & passing messages

•Complicated debugging• As with all distributed systems, debugging & testing is complex

Pros & Cons of the Async Forwarder/Receiver Pattern

Page 84: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

84

Supporting OO Async Communication (1/2)

Context• Some clients want to invoke remote operations, continue their work, & retrieve the results at a later point in time

Problem•Using the explicit message-passing API of the Async Forwarder/Receiver pattern can reduce type-safety & performance•Similar to motivation for Proxy pattern...

Client Server

Request messages

Request messages

Reply messages

Page 85: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

85

Supporting OO Async Communication (2/2)

Solution•Apply the Active Object design pattern (P2) to decouple method invocation from method execution using a strongly-typed OO programming model

Solution•Apply the Active Object design pattern (P2) to decouple method invocation from method execution using a strongly-typed OO programming model

• A proxy provides an interface that allows clients to access methods of an object

• A concrete method request is created for every method invoked on the proxy

• A scheduler receives the method requests & dispatches them on the servant when they become runnable

• An activation list maintains pending method requests

• A servant implements the methods

• A future allows clients to access the results of a method call on the proxy

Future

Scheduler

enqueue dispatch

MethodRequest

guardcall

*

Proxy

method_1method_n

ActivationList

enqueuedequeue

Servant

method_1method_n

creates creates maintains

ConcreteMethodRequest1

ConcreteMethodRequest2

Page 86: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

86

• A client invokes a method on the proxy

• The proxy returns a future to the client, & creates a method request, which it passes to the scheduler

• The scheduler enqueues the method request into the activation list (not shown here)

• When the method request becomes runnable, the scheduler dequeues it from the activation list (not shown here) & executes it in a different thread than the client

• The method request executes the method on the servant & writes results, if any, to the future

• Clients obtain the method’s results via the future

Active Object Pattern Dynamics

: Future

method

enqueue

: Proxy : Scheduler : Servant

: MethodRequest

dispatch call method

read

write

: Client

Clients can obtain result from futures via blocking, polling, or callbacksClients can obtain result from futures via blocking, polling, or callbacks

Page 87: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

87

Applying the Active Object Pattern to Image Acquisition

•OO developers often prefer method-oriented request/response semantics to message-oriented semantics

•The Active Object pattern supports this preference via strongly-typed async method APIs:• Several types of parameters can be passed:• Requests contain in/inout arguments• Results carry out/inout arguments & results

• Callback object or poller object can be used to retrieve results

Future

Scheduler

enqueue dispatch

MethodRequestguardcall

*

Proxy

method_1method_n

ActivationList

enqueuedequeue

Servantmethod_1method_n

creates creates maintains

get_image() put_image()

Image Xfer Service

Image Xfer Service

ImageDatabase

RadiologyClient

RadiologyClient

get_image()

future results

Page 88: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

88

This pattern provides four benefits:•Enhanced type-safety

• Cf. async forwarder/receiver message passing•Enhances concurrency & simplifies synchronized complexity• Concurrency is enhanced by allowing client threads & asynchronous method executions to run simultaneously

• Synchronization complexity is simplified by using a scheduler that evaluates synchronization constraints to serialized access to servants

•Transparent leveraging of available parallelism• Multiple active object methods can execute in parallel if supported by the OS/hardware

•Method execution order can differ from method invocation order• Methods invoked asynchronous are executed according to the synchronization constraints defined by their guards & by scheduling policies

• Methods can be “batched” and sent wholesale to enhance throughput

This pattern also has some liabilities: • Higher overhead• Depending on how an active object’s scheduler is implemented, context switching, synchronization, & data movement overhead may occur when scheduling & executing active object invocations

• Complicated debugging• It is hard to debug programs that use the Active Object pattern due to the concurrency & non-determinism of the various active object schedulers & the underlying OS thread scheduler

Pros & Cons of the Active Object Pattern

Page 89: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

89

Decoupling Suppliers & Consumers (1/2)Problem•Having each client call a specific server is inefficient & non-scalable•A “polling” strategy leads to performance bottlenecks

•Work lists could be spread across different servers

•More than one client may be interested in work list content

Context• In large-scale electronic medical imaging systems, radiologists may share “work lists” of patient images to balance workloads effectively

ImageDatabase

RadiologyClient

RadiologyClient

RadiologyClient

RadiologyClient

RadiologyClient

RadiologyClient

RadiologyClient

RadiologyClient

RadiologyClient

RadiologyClient

Page 90: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

90

Decoupling Suppliers & Consumers (2/2)

Decouple suppliers (publishers) & consumers (subscribers) of events:

• An Event Channel stores/forwards events

• Publishers create events & store them in a queue maintained by the Event Channel

• Consumers register with event queues, from which they retrieve events

• Events are used to transmit state change info from publishers to consumers

• For event transmission push-models & pull-models are possible

• Filters can filter events for consumers

Event

*

Subscriber

consume

creates receives

Event Channel

attachPublisher detachPublisherattachSubscriberdetachSubscriberpushEvent

Filter

filter

Publisher

produce

Solution•Apply the Publisher-Subscriber architectural pattern (P1) to decouple image suppliers from consumers

Solution•Apply the Publisher-Subscriber architectural pattern (P1) to decouple image suppliers from consumers

Page 91: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

91

Publisher-Subscriber Pattern Dynamics

•The Publisher-Subscriber pattern helps keep the state of cooperating components synchronized

•To achieve this it enables one-way propagation of changes: one publisher notifies any number of subscribers about changes to its state

attachSubscriber

produce

pushEventevent

eventpushEvent

consume

detachSubscriber

: Event

: Subscriber: Event Channel: Publisher

Key design considerations for the Publisher-Subscriber pattern include:•Push vs. pull interaction models•Control vs. data event notification models•Multicast vs. unicast communication models•Persistence vs. transient queueing models

Key design considerations for the Publisher-Subscriber pattern include:•Push vs. pull interaction models•Control vs. data event notification models•Multicast vs. unicast communication models•Persistence vs. transient queueing models

Page 92: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

92

Applying the Publisher-Subscriber Pattern to Image Acquisition

Event

*

Radiologist

consume

creates receives

Event ChannelattachPublisher detachPublisherattachSubscriberdetachSubscriberpushEvent

Filter

filter

Modality

produce

ImageDatabase

RadiologyClient

RadiologyClient

RadiologyClient

RadiologyClient

RadiologyClient

RadiologyClient

RadiologyClient

RadiologyClient

RadiologyClient

RadiologyClient

EventChannelEvent

Channel

•Radiologists can subscribe to an event channel to receive notifications produced when modalities publish events indicating the arrival of new images & studies

•This design enables a group of distributed radiologists to collaborate effectively in a networked environment

Page 93: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

93

Pros & Cons of the Publisher-Subscriber Pattern

This pattern has two benefits:•Decouples consumers & producers of events• All an event channel knows is that it has a list of consumers, each conforming to the simple interface of the Subscriber class

• The coupling between the publishers & subscribers is therefore abstract, anonymous, & minimal

•n:m communication models are supported• Unlike an ordinary sync/async request/response invocation, the notification that a publisher sends needn’t designate its receiver, which enables a broader range of communication topologies, including multicast & broadcast

There is also a liability:•Must be careful with potential update cascades• Since subscribers have no knowledge of each other’s presence, applications may not recognize the ultimate cost of publishing events through an event channel

• A seemingly innocuous operation on the subject may therefore cause a cascade of updates to observers & their dependent objects

Page 94: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

94

Locating & Creating Components Scalably (1/2)

Context• Our electronic medical imaging system contains many components distributed in a network

Problem•How to create new components and/or find existing ones

•Simple solutions appropriate for stand-alone applications don’t scale

•“Obvious” distributed solutions also don’t scale

Modalitiese.g., MRI, CT, CR,

Ultrasound, etc.

Modalitiese.g., MRI, CT, CR,

Ultrasound, etc.

Page 95: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

95

Locating & Creating Components Scalably (2/2)

• An Abstract Home declares an interface for operations that find and/or create abstract instances of components

• Concrete Homes implements the abstract Home interface to find specific instances and/or create new ones

• Abstract Comp declares interface for a specific type of component class

• Concrete Comp define instances

• A Primary Key is associated with a component

Solution•Apply the Factory/Finder design pattern to separate the management of component lifecycles from their use by client applications

Solution•Apply the Factory/Finder design pattern to separate the management of component lifecycles from their use by client applications

AbstractComp

operation

ConcreteComp

operation

Primary Key

ConcreteHome

findcreate

AbstractHome

findcreate

Page 96: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

96

Factory/Finder Pattern Dynamics

• Homes enable the creation & location of components, but we still need some type of general-purpose naming/directory service to locate the homes

• Homes enable the creation & location of components, but we still need some type of general-purpose naming/directory service to locate the homes

find (“ImageXYZ”); Primary Key

Component

operation

lookup

: Client : Home : Component

: Primary Keycreate

Node

Binding Directory

*

resolvelistNodesnavigatenewBindingnewSubDirremove

getName

getObject

Client

•The Factory/Finder pattern is supported by distributed component models•e.g., EJB, COM+, & the CCM

Page 97: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

97

Applying the Factory/Finder Pattern to Image Acquisition

AbstractComp

operation

ImageXferComp

operation

Primary Key

ImageXferHome

findcreate

AbstractHome

findcreate

1. Deploy

2. BindFactory

Image Xfer Interface

Image Xfer Interface

4. Intercept & delegate

Factory ProxyFactory Proxy6. Find Image

Factory/FinderFactory/Finder

NamingServiceNamingService

3. Find Factory

ImageDatabase

RadiologyClient

RadiologyClient

5.New

ConfigurationConfiguration

ContainerContainer

•We can apply the Factory/Finder pattern to create/locate image transfer components for images needed by radiologists

• If a suitable component already exists the component home will use it, otherwise, it will create a new component

Page 98: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

98

Pros & Cons of the Factory/Finder Pattern

This pattern has three benefits:•Separation of concerns

• Finding/creating individual components is decoupled from locating the factories that find/create these components

• Improved scalability• e.g., general-purpose directory mechanisms need not manage the creation & location of large amounts of finer-grained components whose lifetimes may be short

•Customized capabilities• The location/creation mechanism can be specialized to support key capabilities that are unique for various types of components

This pattern also has some liabilities:•Overhead due to indirection

• Clients must incur the overhead of several round-trips to obtain the appropriate object reference

•Complexity & cost for development & deployment• There are more steps involved in obtaining object references, which can complicate client programming

Page 99: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

99

Context•Component developers may not know a priori the context in which their components will execute

•Thus, containers are introduced to:• Shield clients & components from the details of the underlying middleware, services, network, & OS

• Manage the lifecycle of components & notify them about lifecycle events

• e.g., activation, passivation, & transaction progress

• Provide components with uniform access to middleware infrastructure services

• e.g., transactions, security, & persistence

• Register & deploy components

DeclarativeProgramming

Server Component

TransactionSecurityResources...

Server Component

TransactionSecurityResources...

...

ImperativeProgramming

Container

Client Client

Extending Components Transparently

Page 100: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

100

Extending Components Transparently (cont‘d)

Problem• Developers should be able to specify declaratively what type of execution environment components need•e.g., in configuration files or databases

• Containers must be able to transparently provide the right execution environment•e.g., by creating a new transaction or new servant when required • Framework represents the concrete

framework to which we attach interceptors• Concrete Interceptors implement the event handler for the system-specific events they have subscribed for

• Context contains information about the event & allows modification of system behavior after interceptor completion

• The Dispatcher allows applications to register & remove interceptors with the framework & to delegate events to interceptors

Context

ConcreteInterceptor

handle_event*

callbackcallback

provideprovide

Dispatcher

attachattach

Framework

attach_interceptormanage_interceptorsAbstractInterceptor

handle_event

Solution•Apply the Interceptor architectural pattern (P2) to attach interceptors to a framework that can handle particular events by invoking associated interceptors automatically

Solution•Apply the Interceptor architectural pattern (P2) to attach interceptors to a framework that can handle particular events by invoking associated interceptors automatically

Page 101: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

101

Interceptor Pattern Dynamics

• Interceptor are a “meta-programming mechanism,” along with•Smart proxies•Pluggable protocols•Gateways/bridges• Interface repositories

•These mechanisms provide building-blocks to handle (often unanticipated) variation translucently & reflectively

•More information on meta-programming mechanisms can be found at

• Interception is commonly used to handle security & transactions transparently from the perspective of a component implementation

• It can also enable performance enhancement strategies • e.g., just-in-time activation, object pooling, load balancing, & caching

: Application: Framework

: Interceptorcreate

run_event_loop

attachinterceptor

Place interceptor in internal interceptor map

event

Look for registered interceptors

: Contextcreate

context

handle_event

: Dispatcher

delegate

www.cs.wustl.edu/~schmidt/PDF/IEEE.pdf

Page 102: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

102

Context

Container

handle_event*

callbackcallback

provideprovide

Dispatcher

attachattach

Image ServerFramework

attach_interceptormanage_interceptorsAbstractInterceptor

handle_event

Applying the Interceptor Pattern to Image Acquisition

• A container provides generic interfaces to a component that it can use to access container functionality •e.g., transaction control, persistence, security,load balancing etc.

• A container intercepts all incoming requests from clients, e.g.,• It can read the component’s requirements from a XML configuration file

• It can then do some pre-processing before actually delegating the request to the component

• A component provides interfaces that its container invokes automatically when particular events occur •e.g., activation or passivation

Container

Component

XMLconfig

Interceptors are used for many other middleware tasks, as well

Page 103: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

103

Pros & Cons of the Interceptor Pattern

This pattern has five benefits:•Extensibility & flexibility

• Interceptors allow an application to evolve without breaking existing APIs & components

•Separation of concerns• Interceptors decouple the “functional” path from the “meta” path

•Support for monitoring & control of frameworks• e.g., generic logging mechanisms can be used to unobtrusively track application behavior

•Layer symmetry• Interceptors can perform transformations on a client-side whose inverse are performed on the server-side

•Reusability• Interceptors can be reused for various general-purpose behaviors

This pattern also has liabilities:•Complex design issues

• Determining interceptor APIs & semantics is non-trivial

•Malicious or erroneous interceptors• Mis-behaving interceptors can wreak havoc on application stability

•Potential interception cascades• Interceptors can result in infinite recursion

Page 104: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

104

Minimizing Resource Utilization (1/2)

Problem• It may not feasible to have all image server implementations running all the time since this ties up end-system resources unnecessarily

Context• Image servers are simply one of many services running throughout a distributed electronic medical image system

Page 105: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

105

Solution• Apply the Activator design pattern to spawn servers on-demand in order to minimize end-system resource utilization

Solution• Apply the Activator design pattern to spawn servers on-demand in order to minimize end-system resource utilization

• When incoming requests arrive, the Activator looks up whether a target object is already active & if the object is not running it activates the implementation

• The Activation Table stores associations between services & their physical location

• The Client uses the Activator to get service access

• A Service implements a specific type of functionality that it provides to clients

Activator

(de)activategetServiceregisterunregisteronShutdown

Activation Table

insertEntryremoveEntrylookupEntrychangeEntry

Service

serviceshutdown

getServicegetService

Client

useService

Minimizing Resource Utilization (2/2)

Page 106: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

106

Activator Pattern Dynamics

: Activator : Client

getService

: Implementationactivate

lookupEntry

[not active]

changeEntryobject

service

result

port

onShutdown

changeEntry

: Activation Table

• An Activator can be used to activate & passivate a server• e.g., after each method call, after each transaction, etc.

•A container/component in a server can also passivate the server itself

• An Activator can be used to activate & passivate a server• e.g., after each method call, after each transaction, etc.

•A container/component in a server can also passivate the server itself

Page 107: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

107

ImR (ringil:5000)Client

ringil:4500plane.exe airplane_poa

server.exepoa_name ringil:5500iiop://ringil:5000/poa_name/object_name

Applying the Activator Pattern to Image Acquisition

Activator

(de)activategetServiceregisterunregisteronShutdown

Activation Table

insertEntryremoveEntrylookupEntrychangeEntry

getServicegetService

Client

useService

ImageXferService

serviceshutdown

Server (ringil:5500)

1. some_request

4. LOCATION_FORWARD

2. ping3. is_running

6. some_response

5. some_request

2.1 start

•The Activator pattern is available in various COTS technologies:•UNIX Inetd “super server”•CORBA Implementation Repository

•We can use the Activator pattern to launch image transfer servers on-demand

iiop://ringil:5500/poa_name/object_name

Page 108: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

108

Pros & Cons of the Activator PatternThis pattern has three benefits:•More effective resource utilization• Servers can be spawned “on-demand,” thereby minimizing resource utilization until clients actually require them

•Uniformity• By imposing a uniform activation interface to spawn & control servers

•Modularity, testability, & reusability• Application modularity & reusability is improved by decoupling server implementations from the manner in which the servers are activated

This pattern also has liabilities:•Lack of determinism & ordering dependencies• This pattern makes it hard to determine or analyze the behavior of an application until its components are activated at run-time

•Reduced security or reliability• An application that uses the Activator pattern may be less secure or reliable than an equivalent statically-configured application

• Increased run-time overhead & infrastructure complexity• By adding levels of abstraction & indirection when activating & executing components

Page 109: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

109

Enhancing Server (Re)Configurability (1/2)

•Certain factors are static, such as the number of available CPUs & operating system support for asynchronous I/O

•Other factors are dynamic, such as system workload

ContextThe implementation of certain image server components depends on a variety of factors:

ProblemPrematurely committing to a particular image server component configuration is inflexible & inefficient:

•No single image server configuration is optimal for all use cases

•Certain design decisions cannot be made efficiently until run-time

ImageProcessing

ConnMgmt

CacheMgmt Threading

Demuxing FileSystem

I/O

Page 110: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

110

Enhancing Server (Re)Configurability (2/2)

•This pattern allows an application to link & unlink its component implementations at run-time

•Thus, new & enhanced services can be added without having to modify, recompile, statically relink, or shut down & restart a running application

Solution•Apply the Component Configurator design pattern (P2) to enhance server configurability

Solution•Apply the Component Configurator design pattern (P2) to enhance server configurability

<<contains>>

components*

ComponentConfigurator

ComponentRepository

ConcreteComponent A

ConcreteComponent B

Component init() fini() suspend() resume() info()

Page 111: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

111

Component Configurator Pattern Dynamics

: ComponentConfigurator

init()

: ConcreteComponent A

: ConcreteComponent B

: ComponentRepository

insert()

insert()

init()

Concrete

run_component()

run_component()

fini()

remove()

remove()

fini()

Comp. A

ConcreteComp. B

ConcreteComp. A

ConcreteComp. B

1.Component initialization & dynamic linking

2.Component processing

3.Component termination & dynamic unlinking

Page 112: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

112

Applying the Component Configurator Pattern to Image Acquisition

<<contains>>

components*

Component

Configurator

ComponentRepository

LRUFile Cache

LFUFile Cache

Component init()

fini() suspend() resume() info()

•For example, an image server can apply the Component Configurator pattern to configure various Cached Virtual Filesystem strategies•e.g., least-recently used (LRU) or least-frequently used (LFU)

Image servers can use the Component Configurator pattern to dynamically optimize, control, & reconfigure the behavior of its components at installation-time or during run-time

Concrete components can be packaged into a suitable unit of configuration, such as a dynamically linked library (DLL)

Concrete components can be packaged into a suitable unit of configuration, such as a dynamically linked library (DLL)

Only the components that are currently in use need to be configured into an image server

Only the components that are currently in use need to be configured into an image server

Page 113: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

113

Reconfiguring an Image ServerImage servers can also be reconfigured dynamically to support new components & new component implementations

IDLE

RUNNING

SUSPENDED

CONFIGUREinit()

RECONFIGUREinit()

fini()

fini()

resume()

suspend()

EXECUTErun_component()

SUSPEND

RESUME

TERMINATE

TERMINATE

Reconfiguration State Chart

LRU FileCache

ImageServer

# Configure an image server.dynamic File_Cache Component *

img_server.dll:make_File_Cache() "-t LRU"

INITIAL CONFIGURATION

AFTER RECONFIGURATION

LFU FileCache

ImageServer

# Reconfigure an image server.Remove File_Cachedynamic File_Cache Component *

img_server.dll:make_File_Cache() "-t LFU"

Page 114: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

114

Pros and Cons of the Component Configurator Pattern

This pattern offers four benefits:•Uniformity

• By imposing a uniform configuration & control interface to manage components

•Centralized administration• By grouping one or more components into a single administrative unit that simplifies development by centralizing common component initialization & termination activities

•Modularity, testability, & reusability• Application modularity & reusability is improved by decoupling component implementations from the manner in which the components are configured into processes

•Configuration dynamism & control• By enabling a component to be dynamically reconfigured without modifying, recompiling, statically relinking existing code & without restarting the component or other active components with which it is collocated

This pattern also incurs liabilities:•Lack of determinism & ordering dependencies• This pattern makes it hard to determine or analyze the behavior of an application until its components are configured at run-time

•Reduced security or reliability• An application that uses the Component Configurator pattern may be less secure or reliable than an equivalent statically-configured application

• Increased run-time overhead & infrastructure complexity• By adding levels of abstraction & indirection when executing components

•Overly narrow common interfaces • The initialization or termination of a component may be too complicated or too tightly coupled with its context to be performed in a uniform manner

Page 115: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

115

Tutorial Example:

High-performance Content Delivery Servers

•Support many content delivery server design alternatives seamlessly• e.g., different concurrency & event models

•Design is guided by patterns to leverage time-proven solutions

•Support many content delivery server design alternatives seamlessly• e.g., different concurrency & event models

•Design is guided by patterns to leverage time-proven solutions

Key Solution Characteristics• Implementation is based on ACE framework components to reduce effort & amortize prior effort

•Open-source to control costs & to leverage technology advances

•Implementation is based on ACE framework components to reduce effort & amortize prior effort

•Open-source to control costs & to leverage technology advances

Key System Characteristics •Robust implementation

• e.g., stop malicious clients•Extensible to other protocols

• e.g., HTTP 1.1, IIOP, DICOM•Leverage advanced multi-processor hardware & software

Goal•Download content scalably & efficiently•e.g., images & other multi-media content types

Graphics

Adapter

GUI

Event Dispatcher

Transfer Protocol

e.g. , HTTP 1.0

Requester

File

Cache

Protocol

Handlers

HTML

Parser

HTTP ClientHTTP Server

GET /index.html HTTP/1.0

<H1>POSA page</H1>...

www.posa.uci.edu

TCP/IP Network

OS Kernel

& Protocols

OS Kernel

& Protocols

Page 116: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

116

JAWS Content Server FrameworkKey Sources of Variation•Concurrency models

• e.g.,thread pool vs. thread-per request

•Event demultiplexing models • e.g.,sync vs. async

•File caching models• e.g.,LRU vs. LFU

•Content delivery protocols• e.g.,HTTP 1.0+1.1, HTTP-NG,

IIOP, DICOM

Event Dispatcher• Accepts client connection

request events, receives HTTP GET requests, & coordinates JAWS’s event demultiplexing strategy with its concurrency strategy.

• As events are processed they are dispatched to the appropriate Protocol Handler.

Protocol Handler• Performs parsing & protocol

processing of HTTP request events.

• JAWS Protocol Handler design allows multiple Web protocols, such as HTTP/1.0, HTTP/1.1, & HTTP-NG, to be incorporated into a Web server.

• To add a new protocol, developers just write a new Protocol Handler component & configure it into the JAWS framework.

Cached Virtual Filesystem• Improves Web server

performance by reducing the overhead of file system accesses when processing HTTP GET requests.

• Various caching strategies, such as least-recently used (LRU) or least-frequently used (LFU), can be selected according to the actual or anticipated workload & configured statically or dynamically.

Page 117: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

117

Applying Patterns to Resolve Key JAWS Design Challenges

Patterns help resolve the following common design challenges: •Efficiently demuxing asynchronous operations & completions

•Enhancing Server (Re)Configurability•Transparently parameterizing synchronization into components

•Ensuring locks are released properly•Minimizing unnecessary locking•Synchronizing singletons correctly•Logging access statistics efficiently

•Efficiently demuxing asynchronous operations & completions

•Enhancing Server (Re)Configurability•Transparently parameterizing synchronization into components

•Ensuring locks are released properly•Minimizing unnecessary locking•Synchronizing singletons correctly•Logging access statistics efficiently

•Encapsulating low-level OS APIs•Decoupling event demuxing & connection management from protocol processing

•Scaling up performance via threading• Implementing a synchronized request queue

•Minimizing server threading overhead•Using asynchronous I/O effectively

•Encapsulating low-level OS APIs•Decoupling event demuxing & connection management from protocol processing

•Scaling up performance via threading• Implementing a synchronized request queue

•Minimizing server threading overhead•Using asynchronous I/O effectively

Double-checkedLocking

Optimization

Thread-specific Storage

Component Configurator

Thread-safe Interface

Strategized Locking

Scoped LockingWrapper Facade

Half-Sync/ Half-Async

Monitor Object

Acceptor-Connector

Leader/Followers

Proactor

Reactor

Page 118: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

118

Encapsulating Low-level OS APIs (1/2)

Problem• The diversity of hardware & operating systems makes it hard to build portable & robust Web server software

• Programming directly to low-level OS APIs is tedious, error-prone, & non-portable

Context • A Web server must manage a variety of OS services, including processes, threads, Socket connections, virtual memory, & files

• OS platforms provide low-level APIs written in C to access these services

Win2K Linux LynxOS

Solaris VxWorks

Applications

Page 119: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

119

Encapsulating Low-level OS APIs (2/2)

This pattern encapsulates data & functions provided by existing non-OO APIs within more concise, robust, portable, maintainable, & cohesive OO class interfaces

: Application

method()

: WrapperFacade

: APIFunctionA

functionA()

: APIFunctionB

functionB()

Applicationcalls methods

callsAPI FunctionA()

callsAPI FunctionB()

calls API FunctionC()

void methodN(){functionA();

}

void method1(){functionA();

}functionB();

Wrapper Facade

data

method1()…methodN()

Solution• Apply the Wrapper Facade design pattern (P2) to avoid accessing low-level operating system APIs directly

Solution• Apply the Wrapper Facade design pattern (P2) to avoid accessing low-level operating system APIs directly

Page 120: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

120

Other ACE wrapper facades used in JAWS encapsulate Sockets, process & thread management, memory-mapped files, explicit dynamic linking, & time operations

Other ACE wrapper facades used in JAWS encapsulate Sockets, process & thread management, memory-mapped files, explicit dynamic linking, & time operations

Applying the Wrapper Façade Pattern in JAWS

JAWS uses the wrapper facades defined by ACE to ensure its framework components can run on many OS platforms•e.g., Windows, UNIX, & many real-time operating systems

For example, JAWS uses the ACE_Thread_Mutex wrapper facade in ACE to provide a portable interface to OS mutual exclusion mechanisms

ACE_Thread_Mutex

mutex

acquire()tryacquire()release()

void acquire() {

calls methods

callsmutex_lock()

callsmutex_trylock()

calls mutex_unlock()

void release() {mutex_unlock(mutex);

}mutex_lock(mutex);

}

JAWS

The ACE_Thread_Mutex wrapper in the diagram is implemented using the Solaris thread API

The ACE_Thread_Mutex wrapper in the diagram is implemented using the Solaris thread API

www.cs.wustl.edu/~schmidt/ACE/

ACE_Thread_Mutex is also available for other threading APIs, e.g., VxWorks, LynxOS, Windows, or POSIX threads

ACE_Thread_Mutex is also available for other threading APIs, e.g., VxWorks, LynxOS, Windows, or POSIX threads

Page 121: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

121

Pros and Cons of the Wrapper Façade PatternThis pattern provides three benefits:•Concise, cohesive, & robust higher-level object-oriented programming interfaces• These interfaces reduce the tedium & increase the type-safety of developing applications, which descreases certain types of programming errors

•Portability & maintainability• Wrapper facades can shield application developers from non-portable aspects of lower-level APIs

•Modularity, reusability & configurability• This pattern creates cohesive & reusable class components that can be ‘plugged’ into other components in a wholesale fashion, using object-oriented language features like inheritance & parameterized types

This pattern can incur liabilities:•Loss of functionality

• Whenever an abstraction is layered on top of an existing abstraction it is possible to lose functionality

•Performance degradation• This pattern can degrade performance if several forwarding function calls are made per method

•Programming language & compiler limitations• It may be hard to define wrapper facades for certain languages due to a lack of language support or limitations with compilers

Page 122: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

122

Decoupling Event Demuxing, Connection Management, & Protocol Processing (1/2)

Context

•Web servers can be accessed simultaneously by multiple clients

Client

Client

Client

HTTP GETrequest

Connectrequest

HTTP GETrequest

Web Server

Socket Handles

•They must demux & process multiple types of indication events arriving from clients concurrently

Event Dispatcher

Sockets

select()

•A common way to demux events in a server is to use select()

•Thus, changes to event-demuxing & connection code affects server protocol code directly & may yield subtle bugs, e.g., when porting to use TLI or WaitForMultipleObjects()

if (FD_ISSET (acceptor, &ready_handles)) { int h;

do { h = accept (acceptor, 0, 0); char buf[BUFSIZ]; for (ssize_t i; (i = read (h, buf, BUFSIZ)) > 0; ) write (1, buf, i); } while (h != -1);

Problem•Developers often couple event-demuxing & connection code with protocol-handling code

•This code cannot then be reused directly by other protocols or by other middleware & applications

Page 123: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

123

SolutionApply the Reactor architectural pattern (P2) & the Acceptor-Connector design pattern (P2) to separate the generic event-demultiplexing & connection-management code from the web server’s protocol code

SolutionApply the Reactor architectural pattern (P2) & the Acceptor-Connector design pattern (P2) to separate the generic event-demultiplexing & connection-management code from the web server’s protocol code

Decoupling Event Demuxing, Connection Management, & Protocol Processing (2/2)

Handleowns

dispatches

*

notifies*

*

handle set

Reactor

handle_events()register_handler()remove_handler()

Event Handler

handle_event ()get_handle()

ConnectorSynchronousEvent Demuxer

select ()

<<uses>>

Acceptor

Service Handler

Page 124: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

124

The Reactor Pattern

The Reactor architectural pattern allows event-driven applications to demultiplex & dispatch service requests that are delivered to an application from one or more clients.

Handleowns

dispatches

*

notifies*

*

handle set

Reactor

handle_events()register_handler()remove_handler()

Event Handler

handle_event ()get_handle()

Concrete Event Handler A

handle_event ()get_handle()

Concrete Event Handler B

handle_event ()get_handle()

SynchronousEvent Demuxer

select ()

<<uses>>

Page 125: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

125

Reactor Pattern Dynamics

: Main Program : ConcreteEvent Handler

: Reactor : Synchronous Event

Demultiplexer

register_handler()

get_handle()

handle_events() select()

handle_event()

Handle

Handles

Handles

Con. EventHandler Events

service()

event

Observations

•Note inversion of control

•Also note how long-running event handlers can degrade the QoS since callbacks steal the reactor’s thread!

1. Initialize phase

2. Event handling phase

Page 126: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

126

The Acceptor-Connector PatternThe Acceptor-Connector design pattern decouples the connection & initialization of cooperating peer services in a networked system from the processing performed by the peer services after being connected & initialized.

<<activate>>

owns

*

uses uses

<<creates>>owns

uses

owns

<<activate>>

* * *

***

uses

notifies

notifies notifies

Connector

Connector()connect()complete()handle_event ()

Concrete Service Handler B

Concrete Service Handler A

ConcreteAcceptor

ConcreteConnector

Acceptor

Acceptor()Accept()handle_event ()

peer_acceptor_

Service Handler

open()handle_event ()set_handle()

peer_stream_

Dispatcher

select()handle_events()register_handler()remove_handler()

TransportHandle

TransportHandle

TransportHandle

Page 127: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

127

Acceptor Dynamics

ServiceHandler Events

: Application : Acceptor : Dispatcher

register_handler()

handle_events()

accept()

open()

register_handler()

handle_event()

service()

: ServiceHandler

open()

ACCEPT_EVENTHandle1Acceptor

: Handle2

Handle2

Handle2

1.Passive-mode endpoint initialize phase

2.Service handler initialize phase

3.Service processing phase

•The Acceptor ensures that passive-mode transport endpoints aren’t used to read/write data accidentally•And vice versa for data transport endpoints…

•There is typically one Acceptor factory per-service/per-port•Additional demuxing can be done at higher layers, a la CORBA

Page 128: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

128

Synchronous Connector Dynamics

Handle

Addr

: Application : Connector : Dispatcher: ServiceHandler

handle_events()

connect()

open()

register_handler()

handle_event()

service()

ServiceHandler

EventsServiceHandler Handle

get_handle()

Motivation for Synchrony

1.Sync connection initiation phase

2.Service handler initialize phase

3.Service processing phase

• If the services must be initialized in a fixed order & the client can’t perform useful work until all connections are established

•If connection latency is negligible•e.g., connecting with a server on the same host via a ‘loopback’ device

• If multiple threads of control are available & it is efficient to use a thread-per-connection to connect each service handler synchronously

Page 129: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

129

Asynchronous Connector Dynamics

Addr

: Application : Connector : Dispatcher: ServiceHandler

handle_events()

complete()

connect()

open()

register_handler()

handle_event()

service()

ServiceHandler

ConnectorCONNECT

EVENT

Events

register_handler()ServiceHandler

HandleHandle

Handle

get_handle()

Motivation for Asynchrony

1.Async connection initiation phase

2.Service handler initialize phase

3.Service processing phase

• If client is initializing many peers that can be connected in an arbitrary order

• If client is establishing connections over high latency links

• If client is a single-threaded applications

Page 130: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

130

Applying the Reactor and Acceptor-Connector Patterns in JAWS

handle_event ()get_handle()

handle_event ()get_handle()

owns

dispatches*

notifies**

handle set

ACE_Reactor

handle_events()register_handler()remove_handler()

ACE_Event_Handler

handle_event ()get_handle()

HTTPAcceptor

HTTPHandlerSynchronous

Event Demuxer

select ()

<<uses>>

The Reactor architectural pattern decouples: 1.JAWS generic

synchronous event demultiplexing & dispatching logic from

2.The HTTP protocol processing it performs in response to events

1.The connection & initialization of peer client & server HTTP services from

2.The processing activities performed by these peer services after they are connected & initialized

The Acceptor-Connector design pattern can use a Reactor as its Dispatcher in order to help decouple:

ACE_Handle

Page 131: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

131

Reactive Connection Management & Data Transfer in JAWS

Page 132: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

132

Pros and Cons of the Reactor PatternThis pattern offers four benefits:•Separation of concerns

• This pattern decouples application-independent demuxing & dispatching mechanisms from application-specific hook method functionality

•Modularity, reusability, & configurability• This pattern separates event-driven application functionality into several components, which enables the configuration of event handler components that are loosely integrated via a reactor

•Portability• By decoupling the reactor’s interface from the lower-level OS synchronous event demuxing functions used in its implementation, the Reactor pattern improves portability

•Coarse-grained concurrency control • This pattern serializes the invocation of event handlers at the level of event demuxing & dispatching within an application process or thread

This pattern can incur liabilities:•Restricted applicability

• This pattern can be applied efficiently only if the OS supports synchronous event demuxing on handle sets

•Non-pre-emptive• In a single-threaded application, concrete event handlers that borrow the thread of their reactor can run to completion & prevent the reactor from dispatching other event handlers

•Complexity of debugging & testing• It is hard to debug applications structured using this pattern due to its inverted flow of control, which oscillates between the framework infrastructure & the method call-backs on application-specific event handlers

Page 133: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

133

Pros & Cons of Acceptor-Connector PatternThis pattern provides three benefits:•Reusability, portability, & extensibility

• This pattern decouples mechanisms for connecting & initializing service handlers from the service processing performed after service handlers are connected & initialized

•Robustness• This pattern strongly decouples the service handler from the acceptor, which ensures that a passive-mode transport endpoint can’t be used to read or write data accidentally

•Efficiency• This pattern can establish connections actively with many hosts asynchronously & efficiently over long-latency wide area networks

• Asynchrony is important in this situation because a large networked system may have hundreds or thousands of host that must be connected

This pattern also has liabilities:•Additional indirection

• The Acceptor-Connector pattern can incur additional indirection compared to using the underlying network programming interfaces directly

•Additional complexity• The Acceptor-Connector pattern may add unnecessary complexity for simple client applications that connect with only one server & perform one service using a single network programming interface

Page 134: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

134

Overview of Concurrency & Threading•Thus far, our web server has been entirely reactive, which can be a bottleneck for scalable systems

•Multi-threading is essential to develop scalable & robust networked applications, particularly servers

•The next group of slides present a domain analysis of concurrency design dimensions that address the policies & mechanisms governing the proper use of processes, threads, & synchronizers

•We outline the following design dimensions in this discussion:

• Iterative versus concurrent versus reactive servers

•Processes versus threads

•Process/thread spawning strategies

•User versus kernel versus hybrid threading models

•Time-shared versus real-time scheduling classes

Page 135: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

135

Iterative vs. Concurrent Servers

•Iterative/reactive servers handle each client request in its entirety before servicing subsequent requests

•Best suited for short-duration or infrequent services

•Concurrent servers handle multiple requests from clients simultaneously

•Best suited for I/O-bound services or long-duration services

•Also good for busy servers

Page 136: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

136

Multiprocessing vs. Multithreading

•A process provides the context for executing program instructions

•Each process manages certain resources (such as virtual memory, I/O handles, and signal handlers) & is protected from other OS processes via an MMU

•IPC between processes can be complicated & inefficient

•A thread is a sequence of instructions in the context of a process

•Each thread manages certain resources (such as runtime stack, registers, signal masks, priorities, & thread-specific data)

•Threads are not protected from other threads

•IPC between threads can be more efficient than IPC between processes

Page 137: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

137

Thread Pool Eager Spawning Strategies•This strategy prespawns one or more OS processes or threads at server creation time

•These “warm-started” execution resources form a pool that improves response time by incurring service startup overhead before requests are serviced

•Two general types of eager spawning strategies are shown below:

•These strategies based on Half-Sync/Half-Async & Leader/Followers patterns

Page 138: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

138

Thread-per-Request On-demand Spawning Strategy

•On-demand spawning creates a new process or thread in response to the arrival of client connection and/or data requests

•Typically used to implement the thread-per-request and thread-per-connection models

•The primary benefit of on-demand spawning strategies is their reduced consumption of resources

•The drawbacks, however, are that these strategies can degrade performance in heavily loaded servers & determinism in real-time systems due to costs of spawning processes/threads and starting services

Page 139: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

139

The N:1 & 1:1 Threading Models•OS scheduling ensures applications use host CPU resources suitably•Modern OS platforms provide various models for scheduling threads •A key difference between the models is the contention scope in which threads compete for system resources, particularly CPU time

•The two different contention scopes are shown below:

• Process contention scope (aka “user threading”) where threads in the same process compete with each other (but not directly with threads in other processes)

• System contention scope (aka “kernel threading”) where threads compete directly with other system-scope threads, regardless of what process they’re in

Page 140: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

140

The N:M Threading Model•Some operating systems (such as Solaris) offer a combination of the N:1 & 1:1 models, referred to as the ``N:M'‘ hybrid-threading model

•When an application spawns a thread, it can indicate in which contention scope the thread should operate

•The OS threading library creates a user-space thread, but only creates a kernel thread if needed or if the application explicitly requests the system contention scope

•When the OS kernel blocks an LWP, all user threads scheduled onto it by the threads library also block

•However, threads scheduled onto other LWPs in the process can continue to make progress

Page 141: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

141

Scaling Up Performance via Threading Context

• HTTP runs over TCP, which uses flow control to ensure that senders do not produce data more rapidly than slow receivers or congested networks can buffer and process

• Since achieving efficient end-to-end quality of service (QoS) is important to handle heavy Web traffic loads, a Web server must scale up efficiently as its number of clients increases

Problem

• Processing all HTTP GET requests reactively within a single-threaded process does not scale up, because each server CPU time-slice spends much of its time blocked waiting for I/O operations to complete

• Similarly, to improve QoS for all its connected clients, an entire Web server process must not block while waiting for connection flow control to abate so it can finish sending a file to a client

Page 142: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

142

The Half-Sync/Half-Async Pattern

SyncServiceLayer

AsyncService Layer

QueueingLayer

<<read/write>><<read/write>>

<<read/write>>

<<dequeue/enqueue>> <<interrupt>>

Sync Service 1 Sync Service 2 Sync Service 3

ExternalEvent Source

Queue

Async Service

The Half-Sync/Half-Async architectural pattern decouples async & sync service processing in concurrent systems, to simplify programming without unduly reducing performance

Solution•Apply the Half-Sync/Half-Async architectural pattern (P2) to scale up server performance by processing different HTTP requests concurrently in multiple threads

Solution•Apply the Half-Sync/Half-Async architectural pattern (P2) to scale up server performance by processing different HTTP requests concurrently in multiple threads

This solution yields two benefits:1. Threads can be mapped to separate

CPUs to scale up server performance via multi-processing

2. Each thread blocks independently, which prevents a flow-controlled connection from degrading the QoS that other clients receive

Page 143: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

143

• This pattern defines two service processing layers—one async & one sync—along with a queueing layer that allows services to exchange messages between the two layers

: External EventSource

: Async Service : Queue

notification

read()

enqueue()

message

: Sync Service

work()

message

read()

message

work()

notification

Half-Sync/Half-Async Pattern Dynamics

• The pattern allows sync services, such as HTTP protocol processing, to run concurrently, relative both to each other & to async services, such as event demultiplexing

Page 144: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

144

Applying Half-Sync/Half-Async Pattern in JAWS

<<get>><<get>>

<<get>>

<<put>>

<<ready to read>>

SynchronousService Layer

AsynchronousService Layer

QueueingLayer

Worker Thread 1 Worker Thread 3

ACE_ReactorSocket

Event Sources

Request Queue

HTTP AcceptorHTTP Handlers,

Worker Thread 2

•JAWS uses the Half-Sync/Half-Async pattern to process HTTP GET requests synchronously from multiple clients, but concurrently in separate threads

•JAWS uses the Half-Sync/Half-Async pattern to process HTTP GET requests synchronously from multiple clients, but concurrently in separate threads

•The worker thread that removes the request synchronously performs HTTP protocol processing & then transfers the file back to the client

•The worker thread that removes the request synchronously performs HTTP protocol processing & then transfers the file back to the client

• If flow control occurs on its client connection this thread can block without degrading the QoS experienced by clients serviced by other worker threads in the pool

• If flow control occurs on its client connection this thread can block without degrading the QoS experienced by clients serviced by other worker threads in the pool

Page 145: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

145

Pros & Cons of Half-Sync/Half-Async PatternThis pattern has three benefits:•Simplification & performance

• The programming of higher-level synchronous processing services are simplified without degrading the performance of lower-level system services

•Separation of concerns• Synchronization policies in each layer are decoupled so that each layer need not use the same concurrency control strategies

•Centralization of inter-layer communication• Inter-layer communication is centralized at a single access point, because all interaction is mediated by the queueing layer

This pattern also incurs liabilities:•A boundary-crossing penalty may be incurred • This overhead arises from context switching, synchronization, & data copying overhead when data is transferred between the sync & async service layers via the queueing layer

•Higher-level application services may not benefit from the efficiency of async I/O• Depending on the design of operating system or application framework interfaces, it may not be possible for higher-level services to use low-level async I/O devices effectively

•Complexity of debugging & testing • Applications written with this pattern can be hard to debug due its concurrent execution

Page 146: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

146

Context•The Half-Sync/Half-Async pattern contains a queue

•The JAWS Reactor thread is a ‘producer’ that inserts HTTP GET requests into the queue

•Worker pool threads are ‘consumers’ that remove & process queued requests

<<get>><<get>>

<<get>>

<<put>>

Worker Thread 1

Worker Thread 3

ACE_Reactor

Request Queue

HTTP AcceptorHTTP Handlers,

Worker Thread 2

Implementing a Synchronized Request Queue

Problem•A naive implementation of a request queue will incur race conditions or ‘busy waiting’ when multiple threads insert & remove requests •e.g., multiple concurrent producer & consumer threads can corrupt the queue’s internal state if it is not synchronized properly

•Similarly, these threads will ‘busy wait’ when the queue is empty or full, which wastes CPU cycles unnecessarily

Page 147: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

147

The Monitor Object Pattern

•This pattern synchronizes concurrent method execution to ensure that only one method at a time runs within an object

• It also allows an object’s methods to cooperatively schedule their execution sequences

2..*

usesuses *

Monitor Object

sync_method1()sync_methodN()

Monitor Lock

acquire()release()

Client

Monitor Conditionwait()

notify()notify_all()

Solution•Apply the Monitor Object design pattern (P2) to synchronize the queue efficiently & conveniently

Solution•Apply the Monitor Object design pattern (P2) to synchronize the queue efficiently & conveniently

• It’s instructive to compare Monitor Object pattern solutions with Active Object pattern solutions•The key tradeoff is efficiency vs. flexibility

Page 148: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

148

Monitor Object Pattern Dynamics: Monitor

Object: Monitor

Lock: MonitorCondition

sync_method1()

wait()

dowork()

: ClientThread1

: ClientThread2

acquire()

dowork()

acquire()sync_method2()

release()

notify()

dowork()

release()

the OS thread schedulerautomatically suspendsthe client thread

the OS threadschedulerautomatically resumes the clientthread and thesynchronizedmethod

the OS thread scheduleratomically reacquiresthe monitor lock

the OS thread scheduleratomically releasesthe monitor lock

1. Synchronized method invocation & serialization

2. Synchronized method thread suspension

3. Monitor condition notification

4. Synchronized method thread resumption

Page 149: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

149

Applying Monitor Object Pattern in JAWS

The JAWS synchronized request queue implements the queue’s not-empty and not-full monitor conditions via a pair of ACE wrapper facades for POSIX-style condition variables

usesuses 2

Request Queue

put()get()

ACE_Thread_Mutex

acquire()release()

HTTP Handler

ACE_Thread_Condition

wait()signal()broadcast()

WorkerThread

<<put>> <<get>>

•When a worker thread attempts to dequeue an HTTP GET request from an empty queue, the request queue’s get() method atomically releases the monitor lock & the worker thread suspends itself on the not-empty monitor condition

•The thread remains suspended until the queue is no longer empty, which happens when an HTTP_Handler running in the Reactor thread inserts a request into the queue

•When a worker thread attempts to dequeue an HTTP GET request from an empty queue, the request queue’s get() method atomically releases the monitor lock & the worker thread suspends itself on the not-empty monitor condition

•The thread remains suspended until the queue is no longer empty, which happens when an HTTP_Handler running in the Reactor thread inserts a request into the queue

Page 150: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

150

Pros & Cons of Monitor Object PatternThis pattern provides two benefits:•Simplification of concurrency control• The Monitor Object pattern presents a concise programming model for sharing an object among cooperating threads where object synchronization corresponds to method invocations

•Simplification of scheduling method execution• Synchronized methods use their monitor conditions to determine the circumstances under which they should suspend or resume their execution & that of collaborating monitor objects

This pattern can also incur liabilities:•The use of a single monitor lock can limit scalability due to increased contention when multiple threads serialize on a monitor object

•Complicated extensibility semantics • These result from the coupling between a monitor object’s functionality & its synchronization mechanisms

•It is also hard to inherit from a monitor object transparently, due to the inheritance anomaly problem

•Nested monitor lockout• This problem is similar to the preceding liability & can occur when a monitor object is nested within another monitor object

Page 151: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

151

accept()

Minimizing Server Threading Overhead

•When a connection request arrives, the operating system’s transport layer creates a new connected transport endpoint, encapsulates this new endpoint with a data-mode socket handle & passes the handle as the return value from accept()

Context•Socket implementations in certain multi-threaded operating systems provide a concurrent accept() optimization to accept client connection requests & improve the performance of Web servers that implement the HTTP 1.0 protocol as follows:

passive-mode socket handle

accept()

accept()accept()

•The OS allows a pool of threads in a Web server to call accept() on the same passive-mode socket handle

•The OS then schedules one of the threads in the pool to receive this data-mode handle, which it uses to communicate with its connected client

accept()

accept()

Page 152: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

152

Drawbacks with Half-Sync/Half-Async

Solution•Apply the Leader/Followers architectural pattern (P2) to minimize server threading overhead

Solution•Apply the Leader/Followers architectural pattern (P2) to minimize server threading overhead

Problem•Although Half-Sync/Half-Async threading model is more scalable than the purely reactive model, it is not necessarily the most efficient design

•CPU cache updates

<<get>><<get>>

<<get>>

<<put>>

Worker Thread 1

Worker Thread 3

ACE_Reactor

Request Queue

HTTP AcceptorHTTP Handlers,

Worker Thread 2

•e.g., passing a request between the Reactor thread & a worker thread incurs:

•This overhead makes JAWS’ latency unnecessarily high, particularly on operating systems that support the concurrent accept() optimization

•Dynamic memory (de)allocation,

•A context switch, &•Synchronization operations,

Page 153: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

153

The Leader/Followers Pattern

This pattern eliminates the need for—& the overhead of—a separate Reactor thread & synchronized request queue used in the Half-Sync/Half-Async pattern

This pattern eliminates the need for—& the overhead of—a separate Reactor thread & synchronized request queue used in the Half-Sync/Half-Async pattern

The Leader/Followers architectural pattern (P2) provides an efficient concurrency model where multiple threads take turns sharing event sources to detect, demux, dispatch, & process service requests that occur on the event sources

Handles

Handle SetsConcurrent Handles Iterative Handles

Concurrent Handle Sets

UDP Sockets + WaitForMultipleObjects(

)

TCP Sockets + WaitForMultpleObjects()

Iterative Handle Sets

UDP Sockets + select()/poll()

TCP Sockets + select()/poll()

Handleuses

demultiplexes

*

*

Handle Sethandle_events()deactivate_handle()reactivate_handle()select()

Event Handler

handle_event ()get_handle()

Concrete Event Handler B

handle_event ()get_handle()

Concrete Event Handler A

handle_event ()get_handle()

Thread Pool

join()promote_new_leader()

synchronizer

Page 154: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

154

Leader/Followers Pattern Dynamics: Concrete

Event Handler

join()

handle_event()

: ThreadPool

: HandleSet

join()

thread 2 sleepsuntil it becomesthe leader

event

thread 1 sleepsuntil it becomesthe leader

deactivate_handle()

join()

Thread 1 Thread 2

handle_events() reactivate_

handle()

handle_event()

event

thread 2waits for anew event,thread 1processescurrentevent

deactivate_handle()

handle_events()

new_leader()

1.Leader thread demuxing

2.Follower thread promotion

3.Event handler demuxing & event processing

4.Rejoining the thread pool

promote_

Page 155: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

155

Applying Leader/Followers Pattern in JAWS

ACE_Handleuses

demultiplexes

*

*

ACE_TP_Reactorhandle_events()deacitivate_handle()reactivate_handle()select()

ACE_Event_Handler

handle_event ()get_handle()

HTTPAcceptor

handle_event ()get_handle()

HTTPHandler

handle_event ()get_handle()

Thread Pool

join()promote_new_leader()

synchronizer

Two options:1.If platform supports accept()

optimization then the Leader/Followers pattern can be implemented by the OS

2.Otherwise, this pattern can be implemented as a reusable framework •The Half-Sync/Half-Async

design can reorder & prioritize client requests more flexibly, because it has a synchronized request queue implemented using the Monitor Object pattern

• It may be more scalable, because it queues requests in Web server virtual memory, rather than the OS kernel

Although Leader/Followers thread pool design is highly efficient the Half-Sync/Half-Async design may be more appropriate for certain types of servers, e.g.:

Page 156: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

156

Pros & Cons of Leader/Followers PatternThis pattern provides two benefits: •Performance enhancements

• This can improve performance as follows: • It enhances CPU cache affinity and eliminates the need for dynamic memory allocation & data buffer sharing between threads

• It minimizes locking overhead by not exchanging data between threads, thereby reducing thread synchronization

• It can minimize priority inversion because no extra queueing is introduced in the server

• It doesn’t require a context switch to handle each event, reducing dispatching latency

•Programming simplicity• The Leader/Follower pattern simplifies the programming of concurrency models where multiple threads can receive requests, process responses, & demultiplex connections using a shared handle set

This pattern also incur liabilities:

• Implementation complexity • The advanced variants of the Leader/ Followers pattern are hard to implement

•Lack of flexibility• In the Leader/ Followers model it is hard to discard or reorder events because there is no explicit queue

•Network I/O bottlenecks• The Leader/Followers pattern serializes processing by allowing only a single thread at a time to wait on the handle set, which could become a bottleneck because only one thread at a time can demultiplex I/O events

Page 157: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

157

Using Asynchronous I/O EffectivelyContext•Synchronous multi-threading may not be the most scalable way to implement a Web server on OS platforms that support async I/O more efficiently than synchronous multi-threading

passive-mode socket handle

AcceptEx()AcceptEx()AcceptEx()

I/O CompletionPort

GetQueuedCompletionStatus()

GetQueuedCompletionStatus()

GetQueuedCompletionStatus()

•When these async operations complete, WinNT1.Delivers the associated completion events

containing their results to the Web server2.Processes these events & performs the appropriate

actions before returning to its event loop

•For example, highly-efficient Web servers can be implemented on Windows NT by invoking async Win32 operations that perform the following activities:•Processing indication events, such as TCP CONNECT and HTTP GET requests, via AcceptEx() & ReadFile(), respectively

•Transmitting requested files to clients asynchronously via WriteFile() or TransmitFile()

Page 158: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

158

The Proactor PatternProblem•Developing software that achieves the potential efficiency & scalability of async I/O is hard due to the separation in time & space of async operation invocations & their subsequent completion events

Solution•Apply the Proactor architectural pattern (P2) to make efficient use of async I/O

Solution•Apply the Proactor architectural pattern (P2) to make efficient use of async I/O

Handle

<<executes>>

*

<<uses>>is associated with

<<enqueues>>

<<dequeues>>

<<uses>> <<uses>>Initiator

<<demultiplexes & dispatches>>

<<invokes>>

Event QueueCompletion

AsynchronousOperation Processor

execute_async_op()

AsynchronousOperation

async_op()

AsynchronousEvent Demuxer

get_completion_event()

Proactor

handle_events()

CompletionHandler

handle_event()

ConcreteCompletion

Handler

This pattern allows event-driven applications to efficiently demultiplex & dispatch service requests triggered by the completion of async operations, thereby achieving the performance benefits of

concurrency without incurring its many liabilities

Page 159: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

159

Proactor Pattern Dynamics

Result

CompletionHandler

Completion

: AsynchronousOperation

: Proactor CompletionHandler

exec_async_

handle_

Result

service()

: AsynchronousOperationProcessor

: Initiator

async_operation()

Result

handle_events()

event

event

Ev. Queue

operation ()

: Completion

Event Queue

Result

event()

1. Initiate operation

2. Process operation

3. Run event loop

4. Generate & queue completion event

5. Dequeue completion event & perform completion processing Note similarities & differences with the Reactor pattern, e.g.:

•Both process events via callbacks•However, it’s generally easier to multi-thread a proactor

Note similarities & differences with the Reactor pattern, e.g.:•Both process events via callbacks•However, it’s generally easier to multi-thread a proactor

Page 160: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

160

Applying the Proactor Pattern in JAWSThe Proactor pattern structures the JAWS concurrent server to receive & process requests from multiple clients asynchronously

JAWS HTTP components are split into two parts:1. Operations that execute asynchronously

•e.g., to accept connections & receive client HTTP GET requests

2. The corresponding completion handlers that process the async operation results•e.g., to transmit a file back to a client after an async connection operation completes

ACE_Handle

<<executes>>

*

<<uses>>is associated with

<<enqueues>>

<<dequeues>>

<<uses>> <<uses>>Web Server

<<demultiplexes & dispatches>>

<<invokes>>

I/O Completion Port

Windows NTOperating System

execute_async_op()

AsynchronousOperation

AcceptEx()ReadFile()WriteFile()

AsynchronousEvent Demuxer

GetQueuedCompletionStatus()

ACE_Proactor

handle_events()

ACE_Handler

handle_accept()handle_write_stream()

HTTPAcceptor

HTTPHandler

Page 161: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

161

Proactive Connection Management & Data Transfer in JAWS

Page 162: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

162

Pros & Cons of Proactor PatternThis pattern offers five benefits:•Separation of concerns

• Decouples application-independent async mechanisms from application-specific functionality

•Portability • Improves application portability by allowing its interfaces to be reused independently of the OS event demuxing calls

•Decoupling of threading from concurrency• The async operation processor executes long-duration operations on behalf of initiators so applications can spawn fewer threads

•Performance• Avoids context switching costs by activating only those logical threads of control that have events to process

•Simplification of application synchronization• If concrete completion handlers spawn no threads, application logic can be written with little or no concern for synchronization issues

This pattern incurs some liabilities:•Restricted applicability

• This pattern can be applied most efficiently if the OS supports asynchronous operations natively

•Complexity of programming, debugging, & testing• It is hard to program applications & higher-level system services using asynchrony mechanisms, due to the separation in time & space between operation invocation and completion

•Scheduling, controlling, & canceling asynchronously running operations• Initiators may be unable to control the scheduling order in which asynchronous operations are executed by an asynchronous operation processor

Page 163: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

163

Efficiently Demuxing Asynchronous Operations & Completions

Context• In a proactive Web server async I/O operations will yield I/O completion event responses that must be processed efficiently

Problem•As little overhead as possible should be incurred to determine how the completion handler will demux & process completion events after async operations finish executing

•When a response arrives, the application should spend as little time as possible demultiplexing the completion event to the handler that will process the async operation’s response

•Together with each async operation that a client initiator invokes on a service, transmit information that identifies how the initiator should process the service’s response

Solution•Apply the Asynchronous Completion Token design pattern (P2) to demux & process the responses of asynchronous operations efficiently

Solution•Apply the Asynchronous Completion Token design pattern (P2) to demux & process the responses of asynchronous operations efficiently

•Return this information to the initiator when the operation finishes, so that it can be used to demux the response efficiently, allowing the initiator to process it accordingly

Page 164: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

164

Asynchronous Completion Token PatternStructure and Participants

Dynamic Interactions

handle_event()

Page 165: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

165

Applying the Asynchronous Completion Token Pattern in JAWS

DetailedInteractions

(HTTP_Acceptoris both initiator &

completion handler)

Page 166: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

166

Pros & Cons of Asynchronous Completion Token Pattern

This pattern has some liabilities:•Memory leaks

• Memory leaks can result if initiators use ACTs as pointers to dynamically allocated memory & services fail to return the ACTs, for example if the service crashes

•Authentication• When an ACT is returned to an initiator on completion of an asynchronous event, the initiator may need to authenticate the ACT before using it

•Application re-mapping• If ACTs are used as direct pointers to memory, errors can occur if part of the application is re-mapped in virtual memory

This pattern has four benefits:•Simplified initiator data structures

• Initiators need not maintain complex data structures to associate service responses with completion handlers

•Efficient state acquisition• ACTs are time efficient because they need not require complex parsing of data returned with the service response

•Space efficiency• ACTs can consume minimal data space yet can still provide applications with sufficient information to associate large amounts of state to process asynchronous operation completion actions

•Flexibility• User-defined ACTs are not forced to inherit from an interface to use the service’s ACTs

Page 167: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

167

Enhancing Server (Re)Configurability (1/2)

•Certain factors are static, such as the number of available CPUs & operating system support for asynchronous I/O

•Other factors are dynamic, such as system workload

ContextThe implementation of certain web server components depends on a variety of factors:

ProblemPrematurely committing to a particular web server component configuration is inflexible & inefficient:

•No single web server configuration is optimal for all use cases

•Certain design decisions cannot be made efficiently until run-time

HTTPParsing

ConnMgmt

CacheMgmt Threading

Demuxing FileSystem

I/O

Page 168: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

168

Enhancing Server (Re)Configurability (2/2)

•This pattern allows an application to link & unlink its component implementations at run-time

•Thus, new & enhanced services can be added without having to modify, recompile, statically relink, or shut down & restart a running application

Solution•Apply the Component Configurator design pattern (P2) to enhance server configurability

Solution•Apply the Component Configurator design pattern (P2) to enhance server configurability

<<contains>>

components*

ComponentConfigurator

ComponentRepository

ConcreteComponent A

ConcreteComponent B

Component init() fini() suspend() resume() info()

Page 169: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

169

Component Configurator Pattern Dynamics

: ComponentConfigurator

init()

: ConcreteComponent A

: ConcreteComponent B

: ComponentRepository

insert()

insert()

init()

Concrete

run_component()

run_component()

fini()

remove()

remove()

fini()

Comp. A

ConcreteComp. B

ConcreteComp. A

ConcreteComp. B

1.Component initialization & dynamic linking

2.Component processing

3.Component termination & dynamic unlinking

Page 170: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

170

Applying the Component Configurator Pattern to Content Servers

<<contains>>

components*

Component

Configurator

ComponentRepository

LRUFile Cache

LFUFile Cache

Component init()

fini() suspend() resume() info()

•For example, a content server can apply the Component Configurator pattern to configure various Cached Virtual Filesystem strategies•e.g., least-recently used (LRU) or least-frequently used (LFU)

Image servers can use the Component Configurator pattern to dynamically optimize, control, & reconfigure the behavior of its components at installation-time or during run-time

Concrete components can be packaged into a suitable unit of configuration, such as a dynamically linked library (DLL)

Concrete components can be packaged into a suitable unit of configuration, such as a dynamically linked library (DLL)

Only the components that are currently in use need to be configured into a content server

Only the components that are currently in use need to be configured into a content server

Page 171: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

171

Reconfiguring JAWSImage servers can also be reconfigured dynamically to support new components & new component implementations

IDLE

RUNNING

SUSPENDED

CONFIGUREinit()

RECONFIGUREinit()

fini()

fini()

resume()

suspend()

EXECUTErun_component()

SUSPEND

RESUME

TERMINATE

TERMINATE

Reconfiguration State Chart

LRU FileCache

WebServer

# Configure a image server.dynamic File_Cache Component *

web_server.dll:make_File_Cache() "-t LRU"

INITIAL CONFIGURATION

AFTER RECONFIGURATION

LFU FileCache

WebServer

# Reconfigure a image server.Remove File_Cachedynamic File_Cache Component *

web_server.dll:make_File_Cache() "-t LFU"

Page 172: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

172

Pros & Cons of Component Configurator PatternThis pattern offers four benefits:•Uniformity

• By imposing a uniform configuration & control interface to manage components

•Centralized administration• By grouping one or more components into a single administrative unit that simplifies development by centralizing common component initialization & termination activities

•Modularity, testability, & reusability• Application modularity & reusability is improved by decoupling component implementations from the manner in which the components are configured into processes

•Configuration dynamism & control• By enabling a component to be dynamically reconfigured without modifying, recompiling, statically relinking existing code & without restarting the component or other active components with which it is collocated

This pattern also incurs liabilities:•Lack of determinism & ordering dependencies• This pattern makes it hard to determine or analyze the behavior of an application until its components are configured at run-time

•Reduced security or reliability• An application that uses the Component Configurator pattern may be less secure or reliable than an equivalent statically-configured application

• Increased run-time overhead & infrastructure complexity• By adding levels of abstraction & indirection when executing components

•Overly narrow common interfaces • The initialization or termination of a component may be too complicated or too tightly coupled with its context to be performed in a uniform manner

Page 173: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

173

Transparently Parameterizing Synchronization into Components

Context•The various concurrency patterns described earlier impact component synchronization strategies in various ways

•e.g.,ranging from no locks to readers/writer locks

•In general, components must run efficiently in a variety of concurrency models

Problem•It should be possible to customize JAWS component synchronization mechanisms according to the requirements of particular application use cases & configurations

•Hard-coding synchronization strategies into component implementations is inflexible

•Maintaining multiple versions of components manually is not scalable

Solution•Apply the Strategized Locking design pattern (P2) to parameterize JAWS component synchronization strategies by making them ‘pluggable’ types

Solution•Apply the Strategized Locking design pattern (P2) to parameterize JAWS component synchronization strategies by making them ‘pluggable’ types

•Each type objectifies a particular synchronization strategy, such as a mutex, readers/writer lock, semaphore, or ‘null’ lock

•Instances of these pluggable types can be defined as objects contained within a component, which then uses these objects to synchronize its method implementations efficiently

Page 174: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

174

Applying Polymorphic Strategized Locking in JAWS

class File_Cache {public: // Constructor. File_Cache (Lock &l): lock_ (&l) { }

// A method. const void *lookup (const string &path) const { lock_->acquire(); // Implement the <lookup> method. lock_->release (); }

// ...private: // The polymorphic strategized locking object. mutable Lock *lock_; // Other data members and methods go here...};

Polymorphic Strategized

Locking

class Lock { public: // Acquire and release the lock. virtual void acquire () = 0; virtual void release () = 0;

// ... };class Thread_Mutex : public Lock { // ...};

Define an abstract interface for the locking mechanisms.

Page 175: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

175

Applying Parameterized Strategized Locking in JAWS

template <class LOCK> class File_Cache {public: // A method. const void *lookup (const string &path) const { lock_.acquire (); // Implement the <lookup> method. lock_.release (); }

// ...private: // The polymorphic strategized locking object. mutable LOCK lock_; // Other data members and methods go here...};

Parameterized Strategized

Locking

•Single-threaded file cache.typedef File_Cache<ACE_Null_Mutex>

Content_Cache;•Multi-threaded file cache using a thread mutex.typedef

File_Cache<ACE_Thread_Mutex> Content_Cache;

•Multi-threaded file cache using a readers/writer lock.typedef File_Cache<ACE_RW_Mutex>

Content_Cache;

Note that the various locks need not inherit from a common base

class or use virtual methods!

Note that the various locks need not inherit from a common base

class or use virtual methods!

Page 176: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

176

Pros and Cons of the Strategized Locking Pattern

This pattern provides three benefits:•Enhanced flexibility & customization

• It is straightforward to configure & customize a component for certain concurrency models because the synchronization aspects of components are strategized

•Decreased maintenance effort for components• It is straightforward to add enhancements & bug fixes to a component because there is only one implementation, rather than a separate implementation for each concurrency model

• Improved reuse• Components implemented using this pattern are more reusable, because their locking strategies can be configured orthogonally to their behavior

This pattern also incurs liabilities:•Obtrusive locking

• If templates are used to parameterize locking aspects this will expose the locking strategies to application code

•Over-engineering• Externalizing a locking mechanism by placing it in a component’s interface may actually provide too much flexibility in certain situations •e.g., inexperienced developers may try to parameterize a component with the wrong type of lock, resulting in improper compile- or run-time behavior

Page 177: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

177

Ensuring Locks are Released Properly

Context•Concurrent applications, such as JAWS, contain shared resources that are manipulated by multiple threads concurrently

Problem•Code that shouldn’t execute concurrently must be protected by some type of lock that is acquired & released when control enters & leaves a critical section, respectively

•If programmers must acquire & release locks explicitly, it is hard to ensure that the locks are released in all paths through the code

Solution• In C++, apply the Scoped Locking idiom (P2) to define a guard class whose constructor automatically acquires a lock when control enters a scope & whose destructor automatically releases the lock when control leaves the scope

Solution• In C++, apply the Scoped Locking idiom (P2) to define a guard class whose constructor automatically acquires a lock when control enters a scope & whose destructor automatically releases the lock when control leaves the scope

// A method. const void *lookup (const string &path) const { lock_.acquire (); // The <lookup> method // implementation may return // prematurely… lock_.release (); }

•e.g., in C++ control can leave a scope due to a return, break, continue, or goto statement, as well as from an unhandled exception being propagated out of the scope

Page 178: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

178

Applying the Scoped Locking Idiom in JAWS

template <class LOCK> class ACE_Guard {public: // Store a pointer to the lock and acquire the lock. ACE_Guard (LOCK &lock) : lock_ (&lock) { lock_->acquire (); }

// Release the lock when the guard goes out of scope, ~ACE_Guard () { lock_->release (); }private: // Pointer to the lock we’re managing. LOCK *lock_;};

Generic ACE_Guard Wrapper Facade

template <class LOCK> class File_Cache {public: // A method. const void *lookup (const string &path) const { // Use Scoped Locking idiom to acquire // & release the <lock_> automatically. ACE_Guard<LOCK> guard (*lock); // Implement the <lookup> method. // lock_ released automatically… }

Applying the ACE_GuardInstances of the guard class can be allocated on the run-time stack to acquire & release locks in method or block scopes that define critical sections

Instances of the guard class can be allocated on the run-time stack to acquire & release locks in method or block scopes that define critical sections

Page 179: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

179

Pros and Cons of the Scoped Locking Idiom

This idiom has one benefit:• Increased robustness

• This idiom increases the robustness of concurrent applications by eliminating common programming errors related to synchronization & multi-threading

• By applying the Scoped Locking idiom, locks are acquired & released automatically when control enters and leaves critical sections defined by C++ method & block scopes

This idiom also has liabilities:•Potential for deadlock when used recursively• If a method that uses the Scoped Locking idiom calls itself recursively, ‘self-deadlock’ will occur if the lock is not a ‘recursive’ mutex

•Limitations with language-specific semantics• The Scoped Locking idiom is based on a C++ language feature & therefore will not be integrated with operating system-specific system calls • Thus, locks may not be released automatically when threads or processes abort or exit inside a guarded critical section

• Likewise, they will not be released properly if the standard C longjmp() function is called because this function does not call the destructors of C++ objects as the run-time stack unwinds

Page 180: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

180

Minimizing Unnecessary Locking (1/2)

Context•Components in multi-threaded applications that contain intra-component method calls

•Components that have applied the Strategized Locking pattern

Problem•Thread-safe components should be designed to avoid unnecessary locking

•Thread-safe components should be designed to avoid “self-deadlock”

template <class LOCK> class File_Cache {public: const void *lookup (const string &path) const { ACE_Guard<LOCK> guard (lock_); const void *file_pointer = check_cache (path); if (file_pointer == 0) { insert (path); file_pointer = check_cache (path); } return file_pointer; } void insert (const string &path) { ACE_Guard<LOCK> guard (lock_); // ... insert <path> into cache... }private: mutable LOCK lock_; const void *check_cache (const string &) const;};

Since File_Cache is a template we don’t know the type of lock used to parameterize it.

Page 181: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

181

Minimizing Unnecessary Locking (2/2)

Solution•Apply the Thread-safe Interface design pattern (P2) to minimize locking overhead & ensure that intra-component method calls do not incur ‘self-deadlock’ by trying to reacquire a lock that is held by the component already

Solution•Apply the Thread-safe Interface design pattern (P2) to minimize locking overhead & ensure that intra-component method calls do not incur ‘self-deadlock’ by trying to reacquire a lock that is held by the component already

• Interface methods check•All interface methods, such as C++ public methods, should only acquire/release component lock(s), thereby performing synchronization checks at the ‘border’ of the component.

This pattern structures all components that process intra-component method invocations according two design conventions:

• Implementation methods trust • Implementation methods, such as C++ private and protected methods, should only perform work when called by interface methods.

Page 182: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

182

Applying the Thread-safe Interface Pattern in JAWS

template <class LOCK> class File_Cache {public: // Return a pointer to the memory-mapped file associated with // <path> name, adding it to the cache if it doesn’t exist. const void *lookup (const string &path) const { // Use Scoped Locking to acquire/release lock automatically. ACE_Guard<LOCK> guard (lock_); return lookup_i (path); }private: mutable LOCK lock_; // The strategized locking object.

// This implementation method doesn’t acquire or release // <lock_> and does its work without calling interface methods. const void *lookup_i (const string &path) const { const void *file_pointer = check_cache_i (path); if (file_pointer == 0) {

// If <path> isn’t in cache, insert it & look it up again.

insert_i (path);file_pointer = check_cache_i (path);// The calls to implementation methods <insert_i> and // <check_cache_i> assume that the lock is held & do

work.}return file_pointer;

Note fewer constraints on the type of LOCK…

Page 183: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

183

Pros and Cons of the Thread-safe Interface Pattern

This pattern has some liabilities:•Additional indirection and extra methods

• Each interface method requires at least one implementation method, which increases the footprint of the component & may also add an extra level of method-call indirection for each invocation

•Potential for misuse• OO languages, such as C++ and Java, support class-level rather than object-level access control

• As a result, an object can bypass the public interface to call a private method on another object of the same class, thus bypassing that object’s lock

•Potential overhead • This pattern prevents multiple components from sharing the same lock & prevents locking at a finer granularity than the component, which can increase lock contention

This pattern has three benefits:• Increased robustness

• This pattern ensures that self-deadlock does not occur due to intra-component method calls

•Enhanced performance • This pattern ensures that locks are not acquired or released unnecessarily

•Simplification of software • Separating the locking and functionality concerns can help to simplify both aspects

Page 184: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

184

Synchronizing Singletons Correctly

Context•JAWS uses various singletons to implement components where only one instance is required•e.g., the ACE Reactor, the request queue, etc.

Problem•Singletons can be problematic in multi-threaded programs

class Singleton {public: static Singleton *instance () { if (instance_ == 0) { // Enter critical section. instance_ = new Singleton; // Leave critical section. } return instance_; } void method_1 (); // Other methods omitted.private: static Singleton *instance_; // Initialized to 0 by linker.};

Either too little locking…class Singleton {public: static Singleton *instance () { Guard<Thread_Mutex> g (lock_); if (instance_ == 0) { // Enter critical section. instance_ = new Singleton; // Leave critical section. } return instance_; }private: static Singleton *instance_; // Initialized to 0 by linker. static Thread_Mutex lock_;};

… or too much

Page 185: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

185

The Double-checked Locking Optimization Pattern

Solution•Apply the Double-Checked Locking Optimization design pattern (P2) to reduce contention & synchronization overhead whenever critical sections of code must acquire locks in a thread-safe manner just once during program execution

Solution•Apply the Double-Checked Locking Optimization design pattern (P2) to reduce contention & synchronization overhead whenever critical sections of code must acquire locks in a thread-safe manner just once during program execution

// Perform first-check to// evaluate ‘hint’.if (first_time_in is TRUE) { acquire the mutex // Perform double-check to // avoid race condition. if (first_time_in is TRUE) { execute the critical section set first_time_in to FALSE } release the mutex}

class Singleton {public: static Singleton *instance () { // First check if (instance_ == 0) { Guard<Thread_Mutex> g(lock_); // Double check. if (instance_ == 0) instance_ = new Singleton; } return instance_; }private: static Singleton *instance_; static Thread_Mutex lock_;};

Page 186: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

186

Applying the Double-Checked Locking Optimization Pattern in ACE

template <class TYPE>class ACE_Singleton {public: static TYPE *instance () { // First check if (instance_ == 0) { // Scoped Locking acquires and release lock. ACE_Guard<ACE_Thread_Mutex> guard (lock_); // Double check instance_. if (instance_ == 0) instance_ = new TYPE; } return instance_; }private: static TYPE *instance_; static ACE_Thread_Mutex lock_;};

ACE defines a “singleton adapter” template to automate the double-checked locking optimization

typedef ACE_Singleton <Request_Queue> Request_Queue_Singleton;

Thus, creating a “thread-safe” singleton is easy

Page 187: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

187

Pros and Cons of the Double-Checked Locking Optimization Pattern

This pattern has two benefits:•Minimized locking overhead

• By performing two first-time-in flag checks, this pattern minimizes overhead for the common case

• After the flag is set the first check ensures that subsequent accesses require no further locking

•Prevents race conditions • The second check of the first-time-in flag ensures that the critical section is executed just once

This pattern has some liabilities:•Non-atomic pointer or integral assignment semantics• If an instance_ pointer is used as the flag in a singleton implementation, all bits of the singleton instance_ pointer must be read & written atomically in a single operation

• If the write to memory after the call to new is not atomic, other threads may try to read an invalid pointer

•Multi-processor cache coherency • Certain multi-processor platforms, such as the COMPAQ Alpha & Intel Itanium, perform aggressive memory caching optimizations in which read & write operations can execute ‘out of order’ across multiple CPU caches, such that the CPU cache lines will not be flushed properly if shared data is accessed without locks held

Page 188: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

188

Logging Access Statistics Efficiently

Context•Web servers often need to log certain information•e.g., count number of times web pages are accessed

Problem•Having a central logging object in a multi-threaded server process can become a bottleneck•e.g., due to synchronization required to serialize access by multiple threads

Solution•Apply the Thread-Specific Storage design pattern (P2) to allow multiple threads to use one ‘logically global’ access point to retrieve an object that is local to a thread, without incurring locking overhead on each object access

Solution•Apply the Thread-Specific Storage design pattern (P2) to allow multiple threads to use one ‘logically global’ access point to retrieve an object that is local to a thread, without incurring locking overhead on each object access

Application <<uses>>callsThread

n m

n x mmaintains

mThread-SpecificObject Setget(key)set(key, object)

Thread-SpecificObject Proxy

keymethod1()…methodN()

Thread-SpecificObjectmethod1()…methodN()

Key Factory

create_key()

Page 189: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

189

key 1

key n

thread m

Thread-SpecificObject

Thread-SpecificObject Proxy

Thread-SpecificObject Set

accesses

manages

The application thread identifier, thread-specific object set, & proxy cooperate to obtain the correct thread-specific object

[k,t]

thread 1

Thread-Specific Storage Pattern Dynamics

: Thread-SpecificObject Proxy

method()

: ApplicationThread

: Thread-SpecificObject Set

: Thread-SpecificObject

key

set()

create_key()

: KeyFactory

keyTSObject

Page 190: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

190

class Error_Logger {public: int last_error (); void log (const char *format, ...);};

Applying the Thread-Specific Storage Pattern to JAWS

Application Thread

<<uses>>calls

n m

n x mmaintains

m

Key Factory

create_key()

Thread-SpecificObject Setget(key)set(key, object)

ACE_TSS

key

operator->()

Error_Loggerlast_error()log()…

template <class TYPE>Class ACE_TSS {public: TYPE *operator->() const { TYPE *tss_data = 0; if (!once_) { ACE_Guard<ACE_Thread_Mutex> g (keylock_); if (!once_) { ACE_OS::thr_keycreate (&key_, &cleanup_hook); once_ = true; } } ACE_OS::thr_getspecific (key, (void **) &tss_data); if (tss_data == 0) { tss_data = new TYPE; ACE_OS::thr_setspecific (key, (void *) tss_data); } return tss_data; }private: mutable pthread_key_t key_; mutable bool once_; mutable ACE_Thread_Mutex keylock_; static void cleanup_hook (void *ptr);};

ACE_TSS <Error_Logger> my_logger;// ...if (recv (……) == -1 && my_logger->last_error () != EWOULDBLOCK) my_logger->log (“recv failed, errno = %d”, my_logger->last_error ());};

Page 191: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

191

Pros & Cons of the Thread-Specific Storage Pattern

This pattern has four benefits:•Efficiency

• It’s possible to implement this pattern so that no locking is needed to access thread-specific data

•Ease of use• When encapsulated with wrapper facades, thread-specific storage is easy for application developers to use

•Reusability• By combining this pattern with the Wrapper Façade pattern it’s possible to shield developers from non-portable OS platform characteristics

•Portability• It’s possible to implement portable thread-specific storage mechanisms on most multi-threaded operating systems

This pattern also has liabilities:• It encourages use of thread-specific global objects• Many applications do not require multiple threads to access thread-specific data via a common access point

• In this case, data should be stored so that only the thread owning the data can access it

• It obscures the structure of the system• The use of thread-specific storage potentially makes an application harder to understand, by obscuring the relationships between its components

• It restricts implementation options• Not all languages support parameterized types or smart pointers, which are useful for simplifying the access to thread-specific data

Page 192: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

192

•Patterns & frameworks for concurrent & networked objects•www.posa.uci.edu

•ACE & TAO open-source middleware•www.cs.wustl.edu/~schmidt/ACE.html•www.cs.wustl.edu/~schmidt/TAO.html

•ACE research papers•www.cs.wustl.edu/~schmidt/ACE-papers.html

•Extended ACE & TAO tutorials•UCLA extension, Jan 19-21, 2005•www.cs.wustl.edu/~schmidt/UCLA.html

•ACE books•www.cs.wustl.edu/~schmidt/ACE/

Additional Information

Page 193: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

193

UML models of a software architecture can illustrate how a system is designed, but not why the system is designed in a particular way

Tutorial Example: Applying Patterns to Real-time CORBA

Patterns are used throughout The ACE ORB (TAO) Real-time CORBA implementation to codify expert knowledge & to generate the ORB’s software architecture by capturing recurring structures & dynamics & resolving common design forces

Patterns are used throughout The ACE ORB (TAO) Real-time CORBA implementation to codify expert knowledge & to generate the ORB’s software architecture by capturing recurring structures & dynamics & resolving common design forces

http://www.posa.uci.edu

Page 194: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

194

R&D Context for ACE+TAO+CIAO

Open-source Standards-based COTS

Patterns & Pattern LanguagesStandards-based QoS-enabled Middleware

Our R&D focus: Advancing distruptive technologies to commoditize distributed real-time & embedded (DRE) systems

Model-based Software Development & Domain-specific Languages

Page 195: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

195

TAO–The ACE ORB

Container

ClientOBJREF

in argsoperation()out args +

return

DIIIDL

STUBSORB

INTERFACE

IDLSKEL

Object Adapter

ORB CORE GIOP/IIOP/ESIOPS

Component(Servant)

Services

• More than 500 Ksloc (C++)

• Open-source• Based on ACE wrapper

facades & frameworks• Available on Unix, Win32,

MVS, QNX, VxWorks, LynxOS, VMS, etc.

• Thousands of users around the world

Objective: Advance technology to simplify the development of embedded & real-time systems

Approach: Use standard OO techology & patterns

•Commercially supported by many companies•OCI (www.theaceorb.com)•PrismTech (www.prismtechnologies.com)•And many more

•www.cs.wustl.edu/~schmidt/commercial-support.html

Page 196: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

196

The Evolution of TAO

TAO ORB

• Largely compliant with CORBA 3.0

• No DCOM bridge ;-)

• Pattern-oriented software architecture

• www.posa.uci.edu

• Key capabilities

• QoS-enabled

• Highly configurable

• Pluggable protocols

• IIOP/UIOP

• DIOP

• Shared memory

• SSL

• MIOP

• SCIOP

•TAO can be downloaded from • deuce.doc.wustl.edu/Download.html

Page 197: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

197

The Evolution of TAORT-CORBA• Portable priorities• Protocol properties• Standard synchronizers• Explicit binding mechanisms

• Thread pools

TAO 1.4 (Jan ’04)• Current “official” release of TAO

• Heavily tested & optimized

• Baseline for next OCI & PrismTech supported releases

• www.dre.vanderbilt.edu/ scoreboard

ZEN • RT-CORBA/RT-Java• Alpha now available www.zen.uci.edu

RT-CORBA 1.0

Page 198: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

198

The Evolution of TAO

A/V STREAMING

DYNAMIC/STATICSCHEDULING

A/V Streaming Service• QoS mapping• QoS monitoring• QoS adaptation

ACE QoS API (AQoSA)• GQoS/RAPI & DiffServ• IntServ integrated with A/V Streaming & QuO

• DiffServ integrated with ORB

RT-CORBA 1.0

Static Scheduling (1.0)• Rate monotonic analysisDynamic Scheduling (2.0)• Earliest deadline first• Minimum laxity first• Maximal urgency firstHybrid Dynamic/Static• Demo in WSOA• Kokyu integrated in Summer 2003

Page 199: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

199

The Evolution of TAODYNAMIC/STATIC

SCHEDULINGFT-CORBA

& LOAD BALANCING

FT-CORBA (DOORS)• Entity redundancy• Multiple models

• Cold passive• Warm passive

• IOGR• HA/FT integrated by Winter 2004

Load Balancing• Static & dynamic• Integrated in TAO 1.3• De-centralized LB• OMG LB specification

SSL Support• Integrity • Confidentiality• Authentication (limited)Security Service (CSIv2)• Authentication• Access control• Non-repudiation• Audit• Beta by Winter 2004

A/V STREAMINGSECURITY

RT-CORBA 1.0

Page 200: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

200

The Evolution of TAONOTIFICATIONS

A/V STREAMINGSECURITY

TRANSACTIONS

DYNAMIC/STATICSCHEDULING

FT-CORBA & LOAD

BALANCING

Notification Service•Structured events•Event filtering•QoS properties

• Priority• Expiry times• Order policy

•Compatible w/Events

Real-time Notification Service•Summer 2003

Object TransactionService• Encapsulates RDBMs• www.xots.org

RT-CORBA 1.0

Page 201: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

201

The Evolution of TAONOTIFICATIONS

A/V STREAMINGSECURITY

TRANSACTIONS

DYNAMIC/STATICSCHEDULING

FT-CORBA & LOAD

BALANCING

CORBA ComponentModel (CIAO)• Extension Interfaces• Component navigation• Standardized life-cycles

• QoS-enabled containers

• Reflective collocation• Implements the OMG Deployment & Configuration specification

• 1.0 release by Winter 2004

RT-CORBA 1.0

Page 202: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

202

Middleware

MiddlewareServices

DRE Applications

Operating Sys& Protocols

Hardware & Networks

•Limit to how much application functionality can be factored into reusable COTS middleware, which impedes product-line architectures

•Middleware itself has become extremely complicated to use & provision statically & dynamically

•Component-based DRE systems are very complicated to deploy & configure

•There are now multiple middleware technologies to choose from

IntServ + Diffserv

RTOS + RT Java

RT/DP CORBA + DRTSJ

Load BalancerFT CORBA

Network latency & bandwidth

Workload & Replicas

CPU & memory

Connections & priority bands

CORBA

CORBAServices

CORBAApps

J2EE

J2EEServices

J2EEApps

.NET

.NETServices

.NETApps

The Road Ahead (1/3)

Page 203: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

203

• Develop, validate, & standardize model-driven development (MDD) software technologies that:

1. Model

2. Analyze

3. Synthesize &

4. Provision

multiple layers of middleware & application components that require simultaneous control of multiple quality of service properties end-to-end

• Partial specialization is essential for inter-/intra-layer optimization & advanced product-line architectures

Middleware

MiddlewareServices

DRE Applications

Operating Sys& Protocols

Hardware & Networks

<CONFIGURATION_PASS> <HOME> <…>

<COMPONENT> <ID> <…></ID> <EVENT_SUPPLIER> <…events this component supplies…> </EVENT_SUPPLIER> </COMPONENT> </HOME></CONFIGURATION_PASS>

<CONFIGURATION_PASS> <HOME> <…>

<COMPONENT> <ID> <…></ID> <EVENT_SUPPLIER> <…events this component supplies…> </EVENT_SUPPLIER> </COMPONENT> </HOME></CONFIGURATION_PASS>

Goal is not to replace programmers per se – it is to provide higher-level domain-specific languages for middleware/application developers & users

The Road Ahead (2/3)

Page 204: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

204

Our MDD toolsuite is called CoSMIC (“Component Synthesis using Model Integrated Computing”)

www.dre.vanderbilt.edu/cosmic

The Road Ahead (3/3)

Page 205: Dr. Douglas C. Schmidt d.schmidt@vanderbilt dre.vanderbilt/~schmidt

205

Concluding Remarks•Researchers & developers of distributed applications face common challenges

R&D Synergies

•Patterns, frameworks, & components help to resolve these challenges

•These techniques can yield efficient, scalable, predictable, & flexible middleware & applications

•e.g., connection management, service initialization, error handling, flow & congestion control, event demuxing, distribution, concurrency control, fault tolerance synchronization, scheduling, & persistence

StandardCOTS

R&D

UserNeeds

R&D