• No results found

Programming Without a Call Stack: Event-driven Architectures

N/A
N/A
Protected

Academic year: 2021

Share "Programming Without a Call Stack: Event-driven Architectures"

Copied!
16
0
0

Loading.... (view fulltext now)

Full text

(1)

Programming Without a Call Stack:

Event-driven Architectures

Gregor Hohpe | Google

www.eaipatterns.com

Who's Gregor?

z

Distributed systems, enterprise integration,

service-oriented architectures

z

MQ, MSMQ, JMS, TIBCO, BizTalk, Web Services

z

Write code every day. Share knowledge through

patterns.

Integration

Patterns

Microsoft Press

Enterprise

Integration

Patterns

Addison-Wesley

SOA

Experten-wissen

dpunkt Verlag

Enterprise

Solution

Patterns

Microsoft

Best

Software

Writing I

APress

eaipatterns.com

• Patterns

• Articles

• Blog

(2)

2

Agenda

zIt's All About Coupling

zEvents Everywhere

zEvent-driven Architectures

zDeveloping in an EDA

zCase Study: Building an EDA in Java

TM

In A Connected World It's All About

Coupling

(3)

4

Dynamic Composability

"The ability to build new things from existing pieces."

"The lines are becoming boxes now."

(4)

6

The World is Full of Events

New Order

Address

Changed

Credit Card

Expired

Payment

Declined

E-mail

Bounced

Order

Entry

Mail

Gateway

Ware

house

Event

Cloud

Web

Site

Inventory

Low

Shipping

Partner

Truck

Delayed

Financial

System

Event-Driven Architecture (EDA)

z

Distributed processing, no central control.

z

Nodes respond to incoming events and publish

events in response.

z

Event channels transport events from one node to the

next, usually asynchronously (sender does not wait).

z

Composition through channels.

Node Channel

(5)

8

EDA Defining Qualities

z

Timeliness. Publish events as they occur

instead of waiting for the next batch cycle.

z

Asynchrony. The publishing system does not

wait for the receiving system(s) to process the

event.

z

Fine Grained. Publish single events as

opposed to large aggregated event.

z

Ontology. A nomenclature to classify and

express interest in certain groups of events.

z

Complex Event Processing. Understanding

the relationships between events, for example

aggregation and causality.

A

A

Queue

B

B

Event

A

A

Orders On-Line New Updated

A

A

Composition via Channels

z

Nodes communicate via Channels

z

Sender and receiver need to agree to a common

channel. This is a form of coupling.

z

Sender and receiver have to decide which channel is

“right”. The burden can be shifted between sender

and receiver.

z

Channel namespace provides some structure.

System

B

System

A

publish

Channel X

subscribe

(6)

10

Channel Naming and Semantics

z

Target component

z

Action / Operation

z

Document

z

Event

Credit

Service

Order

Entry

CreditService

VerifyCreditCard

Credit

Service

Order

Entry

Credit

Service

Order

Entry

PaymentInfo

Credit

Service

Order

Entry

OrderReceived

How Do A and B Connect?

z

Channel Name / Instance

Common in message queue systems.

Limited expressiveness.

z

Topic Hierarchy

Allows wildcard subscription

Requires mapping of topic space onto a tree. Forces prioritization.

z

Content-based

Flexible, but difficult to implement efficiently in widely distributed systems.

Orders

On-Line

New

Updated

MessageQueue q = new MessageQueue(“foo"); q.Send(“Msg”); Channel.Subscribe( “/element/foo=‘bar’” ); Structured Unstructured

(7)

12

Composition Strategies

z

Implicit Composition

z

Explicit Composition

A

B

channel = Channel.byName(“orders”); channel.publish(message); channel = Channel.byName(“orders”); channel.publish(message); channel = Channel.byName(“orders”); channel.subscribe(eventHandler); channel = Channel.byName(“orders”); channel.subscribe(eventHandler);

orders

A

B

A(Channel ch) { this.channel = ch; } … channel.publish(message); A(Channel ch) { this.channel = ch; } … channel.publish(message); B(Channel ch) { this.channel = ch; } … channel.subscribe(eventHandler); B(Channel ch) { this.channel = ch; } … channel.subscribe(eventHandler);

“Composer”

Channel Channel <<create>>

Event Collaboration

RequestFor Address Order Management Address SendShipment Customer Management Shipping Order Order Management Address Changed Customer Management Shipping Order

Multiple Components work together by communicating with each other by

sending events when their internal state changes.

Request

Collaboration

Event

Collaboration

(8)

14

Event Collaboration

z

Adding Consumers is Side-Effect Free

Debugging / logging / sniffing

Parallel implementations

z

Simple components, more complex interactions

z

Robust against unstable connections

z

Can be difficult to manage and /or debug

Need to understand relationship between events

Shift burden from design-time to run-time

z

Components may operate on stale data

Event-sourced Systems

Capture all changes to an application state as a

sequence of events.

(Fowler)

Domain Objects Event Bus Event Log Local State State Changes Persisted State (Snapshot)

(9)

16

Event-sourced Systems

z

More than an event log or "temporal database"

z

Rebuild state based on events by re-executing

behavior

z

Temporal Query

Determine application state at specific point in time

z

Event replay

Run "what if" scenarios or corrections to past events

z

Limitation: code changes

Composite Events Processing

z

Understand causality

z

Some events are the result a

of a sequence of events

z

CEP = Complex Event Processing

z

Pattern matching languages

can be challenging

Aggregation Causality

(10)

18

Case Study – Existing System

z

Compute statistics based on responses to on-line

questionnaires

z

Responses stored in database

z

At the end, stored procedure computes “scores” based on

user responses

Load on RDBMS

Single thread, monolithic, synchronous

Poor response time at end of user session

z

Goal: scalable, extensible architecture

On-line DB On-line DB Copy Proc Copy Proc ReportDB Report DB Compute Proc Compute Proc FrontEnd FrontEnd A B C UI Client

Case Study – New Architecture

z

Decompose logic into individual “calculators”

z

Calculators precompute results as response events

arrive

z

Channels connect calculators

z

Calculators do not updates database

z

Persist results into database once all scores computed

z

Pure Java (1.4) implementation

Log

Log

FrontEnd

FrontEnd PersistencePersistence DBDB

A B C UI Client Event-driven Calculators

(11)

20

Design Decisions

z

Point-to-Point vs. Publish-Subscribe Channels

z

Distributed vs. Distributable

z

Asynchronous vs. One-Way

z

Technology Specific vs. Technology Neutral

z

Explicit vs. Implicit Composition

z

Channel Naming “ontology”

String match

Hierarchy

Content-based

z

Automated Dispatch vs. Manual Dispatch

(Class Hierarchy)

Implementation

z

Multiple calculators subscribe to abstract Channel

z

Channel stores subscribers by event type (hierarchy)

z

For each incoming event, channel looks up all subscribers for the

event type and its superclasses

z

For each subscribing class, figure out the overriding onEvent method

with the most specific matching argument

public interface Channel { public void send(Event event);

public void subscribe(EventRecipient recipient, Class eventClass); } Marker Interface Marker Interface

(12)

22

Subscription / Dispatching

Class SomeEvent extends Event {} class SubEvent1 extends SomeEvent {} class SubEvent2 extends SomeEvent {} class SomeSubscriber {

public SomeSubscriber {

channel.subscribe(SomeEvent.class); }

public void onEvent (Event e) {} public void onEvent (SubEvent1 se) {} } SomeEvent SubEvent1 SubEvent2 SubEvent2 invoke Event SubEvent1 invoke No invocation Event

Incoming

Event

Event

Hierarchy

Channel Implementation

public void send(Event event) { Set<EventRecipient> subscribers =

getSubscribersForEventTypeAndItsSuperTypes(event.getClass()); for (EventRecipient recipient : subscribers) {

EventProcessorHelper.invokeEventHandler(event, recipient); }

}

Map<Class, Set<EventRecipient>> subs;

Set<EventRecipient> getSubscribersForEventTypeAndItsSuperTypes

(Class eventClass) {

Set<EventRecipient> allSubscribers = new HashSet<EventRecipient>();

for (Map.Entry<Class, Set<EventRecipient>> entry : subs.entrySet()) { Class subscriberEventClass = entry.getKey();

if (subscriberEventClass.isAssignableFrom(eventClass)) { allSubscribers.addAll(entry.getValue());

} }

return allSubscribers; }

(13)

24

Channel Implementation (Cont'd)

boolean invokeEventHandler(Event event, EventRecipient recip) {

for (Class eventClass = event.getClass(); eventClass != null;

eventClass = eventClass.getSuperclass()) { Method eventHandler = recip.getClass().getMethod

("onEvent", new Class[]{eventClass}); try {

eventHandler.invoke(recip, new Object[] {event}); return true; } catch (…) {…} if (Event.class.equals(eventClass)) return false; } return false; }

Channel Behaviors

public void testEachSubscriberReceivesMessage() {…} public void testSubscribeTwiceReceiveOnce() {…}

public void testBaseClassSubscriberReceivesDerivedClassEvents() {…} public void testSubscribingForNonEventTypeThrows() {…}

public void testInvokesExactlyMatchingMethodForBaseEventType() {…} public void testInvokesExactlyMatchingMethodForEventSubType() {…} public void testDoesNothingForOverlySpecificEventHandler() {…} public void testInvokesMostSpecificMethodIfBothAreAvailable() {…}

(14)

26

Cool Things

z

Testing components in isolation

z

Publish-subscribe enables adding rather than replacing

z

Replay of events to recover transient state

z

Tracing / logging trivial, almost aspect-like

public class DebugCalculator extends Calculator {

public DebugCalculator(Channel channel) { super(channel);

channel.subscribe(this, Event.class); }

public void onEvent(Event event) { System.out.println("event = " + event); } } Base class of all events Base class of all events

(Tough) Lessons Learned

z

Must keep architectural big picture in mind

z

Integration testing more critical – less compile time

validation (the price of loose coupling)

z

Tools essential

Event logger

Dependency visualization (“reverse MDA”)

z

Shared state not always avoidable. Can lead to hidden

dependencies

z

Make minimum necessary assumptions about

sequence of events

(15)

28

Side-By-Side

z

Top-down

z

Design-time composition

z

Sequential

z

Synchronous

z

Predictive

z

Transactional

(Pessimistic)

z

Centralized state

z

Error handling simple

z

Bottom-up

z

Run-time composition

z

Parallel

z

Asynchronous

z

Reactive

z

Compensation / Retry

(Optimistic)

z

Distributed state

z

Error handling more complex

z

Diagnostics more complex

(16)

30

z

Enterprise Integration Patterns

Addison-Wesley, 0-321-20068-3

z

www.eaipatterns.com

Article: Programming without a

Call Stack

Blog ("Ramblings")

z

http://www.martinfowler.com/eaaDev/EventCollaboration.html

z

http://www.martinfowler.com/eaaDev/EventSourcing.html

References

Related documents

In the case of the Swiss watch industry, the value chain of authenticity production mobilises different knowledge (technological but also non-technological) in different

observed in both the intermediate and long delay periods (See Figure 5). As mentioned previously, the insula is often associated to play a part in delaying gratification and

Impingement syndrome is characterized by pain in the shoulder due to inflammation of the tendons of the rotator cuff or the bursa (subacromial bursa) that sits between the rotator

Univariate analysis showed that factors associated with compliance were patient age, how important patients felt it was to take drugs as prescribed, whether patients

I argued for a thesis of literary stylistic representation based on the writings of Virginia Woolf: a literary style represents a set of cognitive dispositions.. The

115 BE IT FURTHER RESOLVED that the Legislature of the state of Utah affirms that, 116 through passage of this legislation, the United States Congress will foster consistent

The follow ing m aterials have been used to m ake u p the device : Steel, Copper, Alum inium , Cast-resin glass-fibre-reinf orced th erm oplast ics, rubber, porcelain, greases

These soft locomotive particles are based on core-shell brush nanoparticles assembled from poly(ionic liquid) as core and thermoresponsive PNIPAM as brush shells on which