reactive computing

37
REACTIVE COMPUTING WITH SCALA EXAMPLES

Upload: stan-lea

Post on 15-Feb-2017

50 views

Category:

Software


1 download

TRANSCRIPT

Page 1: Reactive computing

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

Page 2: Reactive computing

Preview

Page 3: Reactive computing

Snake Game 3

Page 4: Reactive computing

Reactive Design 4

State

State

Snake

Apple

Stream Combinator

Ticker

Input Game State

Move

Turn

Grow

Game

Page 5: Reactive computing

Definitions

Page 6: Reactive computing

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.

Page 7: Reactive computing

Typesafe 7

Page 8: Reactive computing

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

Page 9: Reactive computing

Points to Remember 9

1 Events/Messages

2 Observer/Observable

3 Streams

4 Composition

5 Reacting

6 Effects

Page 10: Reactive computing

Computing Concepts Overview

Page 11: Reactive computing

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

Page 12: Reactive computing

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

Page 13: Reactive computing

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

Page 14: Reactive computing

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

Page 15: Reactive computing

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

Page 16: Reactive computing

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

Page 17: Reactive computing

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

Page 18: Reactive computing

Streams

Page 19: Reactive computing

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.

Page 20: Reactive computing

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

Page 21: Reactive computing

Subscriber API 21

Page 22: Reactive computing

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]()

Page 23: Reactive computing

map 23

Page 24: Reactive computing

filter 24

Page 25: Reactive computing

combineLatest 25

Page 26: Reactive computing

scan 26

Page 27: Reactive computing

Reactive Snake Game

Page 28: Reactive computing

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

Page 29: Reactive computing

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

Page 30: Reactive computing

Industry Standardization

Page 31: Reactive computing

Reactive Streams 31

Page 32: Reactive computing

Reactive Streams Flow 32

Page 33: Reactive computing

State Subjects

Page 34: Reactive computing

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

Page 35: Reactive computing

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

Page 36: Reactive computing

Comparison 36

Domain-Like Entities

Service-Like

filter-scan-map

4

5

63

2

1Similar to Actors

Similar to Objects

Composable

State Subject

State

Page 37: Reactive computing

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