Reactive computing

Preview:

Citation preview

REACTIVE COMPUTINGW I T H S C A L A E X A M P L E S

Preview

Snake Game 3

Reactive Design 4

State

State

Snake

Apple

Stream Combinator

Ticker

Input Game State

Move

Turn

Grow

Game

Definitions

Academia 6

A reactive system is a system that, when switched on, is able to create desirable effects in its environment

by reacting to events.

Typesafe 7

ReactiveX 8

The Observer pattern done right

ReactiveX is a combination of the best ideas from the Observer pattern, the Iterator pattern, and

functional programming

Points to Remember 9

1 Events/Messages

2 Observer/Observable

3 Streams

4 Composition

5 Reacting

6 Effects

Computing Concepts Overview

Functions 11

INPUT Needs to be passed in and can be thought of as a single value

CALLER Holds references to the function, input and output and it typically blocks to wait for the output (pulls returned values)

OUTPUT Can be a value, another function, Future, etc.

f

Input

Output

Generators and Iterators 12

NO INPUT

EXAMPLES Python yield, Scala yield, ES7, random number generators, collections exposed as iterators

OUTPUT Varies based on some state and needs to indicate termination

f

Output

Objects 13

ENCAPSULATED STATE Typically not exposed directly

CALLER Holds references to objects, and it typically blocks to wait for the methods’ return values

PUBLIC INTERFACE Methods are passed arguments and return values

mInput

Output

State

Publ

ic M

etho

ds

Function/Object Composition 14

Input

Output

f

g

h

PROGRAMS Can be seen as an orchestration of functions and object methods calls

COORDINATION Function calls need to be coordinated (think concurrency, blocking, synchronicity)

EXECUTION Sequence of pushing and pulling values to and from functions/methods calls

Queues 15

PRODUCERS Push values to the queue instead of directly to consumers

QUEUES Decouple producers from consumers and help with coordination (threads, waits, delays, etc.)

CONSUMERS Pull values from the queue

Producers Consumers

Actors 16

ACTORS Receive messages asynchronously on an internal queue

OUTPUT Is optionally sent to another actor

MESSAGES Are pulled sequentially and processed by a partial function

State

Observer Pattern 17

OBSERVABLE/SUBJECT Pushes values to registered observers/subscribers

NO DECOUPLING QUEUE Between the observable and observers, but the observable could use one internally

OBSERVERS Process values pushed by the observable

Observable/Subject

Observers

abstract class SubjectObserver { type S <: Subject type O <: Observer trait Subject { // self-type annotation // we can now use "self" as an alias for "this" self: S => private var observers = List[O]() def addObserver(observer: O) = observers ::= observer def notifyObservers = observers foreach (_.onUpdate(self)) } trait Observer { def onUpdate(subject: S) }}

Streams

ReactiveX 19

An API for asynchronous programming with observable streams

CREATE Easily create event streams or data streams.

COMBINE Compose and transform streams with query-like operators.

LISTEN Subscribe to any observable stream to perform side effects.

Observable Streams 20

OBSERVABLE Pushes values and errors to registered observers/subscribers

COMPOSITION Observables can be composed with an intuitive DSL

OBSERVERS Implement onNext, onError and onCompleted and are registered with the observable

Observable

Observers

Subscriber API 21

Examples 22

CREATE

COMBINE AND LISTENsnakeObservable.combineLatest(appleObservable).subscribe( pair => { Game.update(pair._1.body, pair._2) }, (t: Throwable) => t.printStackTrace(), () => {}) tick.subscribe( _ => events.onNext(Move()), (t: Throwable) => println("tick error : " + t), () => {})

val tick = Observable.interval(Duration(150, TimeUnit.MILLISECONDS))

val events: PublishSubject[Event] = PublishSubject[Event]()

map 23

filter 24

combineLatest 25

scan 26

Reactive Snake Game

Observable Snake 28

EVENTS Keyboard events are converted to semantic events and streamed

COMPOSITION Stream operators are used to compose observables

STATE PUBLISHING Event processing results in internal state changes that are published/streamed for view consumption

Scala Code 29

IMMUTABLE SNAKE STATE

SNAKE EVENTS PROCESSING AND STATE PUBLISHING

case class Snake(body: List[WorldLocation], direction: WorldLocation) { def go(toDirection: WorldLocation): Snake = Snake(body, toDirection) def moved: Snake = Snake((head + direction) :: body.take(body.size - 1), direction) def grown: Snake = Snake((head + direction) :: body, direction) def head: WorldLocation = body.head}

def createSnake(init: Snake, events: Observable[Event]): Observable[Snake] = { events .scan(init)((snake, event) => event match { case Move() => snake.moved case Grow() => snake.grown case Turn(direction) => snake.go(direction) })}

APPLE EVENTS PROCESSING AND STATE PUBLISHINGdef createApple(init: WorldLocation, snakeObservable: Observable[Snake], events: Subject[Event, Event]): Observable[WorldLocation] = { snakeObservable.scan(randomLocation())((loc: WorldLocation, snake: Snake) => snake.head match { case head if head == loc => events.onNext(Grow()) randomLocation() case _ => loc })}

Industry Standardization

Reactive Streams 31

Reactive Streams Flow 32

State Subjects

Computation Ingredients 34

Event ProcessorThe processor can be thought of as a partial function whose domain consists of all possible events and whose output is the new internal state.

External State/ValueInternal state is converted to ideally one single external value to be published on change

Internal StateIf the computation is

stateful then the initial state evolves based on the

events that are subsequently processed

State Subjects 35

SUBJECT The component is both subscribing and publishing events

OUTPUT The external value(s) are published so any subscriber can read to them

MESSAGE PASSING No methods and no return values

State

Comparison 36

Domain-Like Entities

Service-Like

filter-scan-map

4

5

63

2

1Similar to Actors

Similar to Objects

Composable

State Subject

State

Alan Kay 37

It was probably in 1967 when someone asked me what I was doing, and I said: "It's object-oriented programming”.

I thought of objects being like biological cells and/or individual computers on a network, only able to communicate with messages.

The key in making great and growable systems is much more to design how its modules communicate rather than what their internal properties and behaviors should be.

http://c2.com/cgi/wiki?AlanKayOnMessaging

http://userpage.fu-berlin.de/~ram/pub/pub_jf47ht81Ht/doc_kay_oop_en

Recommended