Upload
stan-lea
View
51
Download
1
Embed Size (px)
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