Slide 1

Slide 1 text

1 RX & Hystrix Kata 2015 RxJava Reactive eXtensions for JVM

Slide 2

Slide 2 text

But first, let me introduce myself… 2

Slide 3

Slide 3 text

Talk agenda • Problem statement • Reactive programming concept • Brief history of reactive extensions (RX) • RxJava API contract • Functional operators • Schedulers • Subjects • Dealing with back-pressure 3

Slide 4

Slide 4 text

Problem 4 Statement: asynchronous programming is hard and error-prone but still extremely indispensable

Slide 5

Slide 5 text

Possible approaches • Future, • Guava’s ListenableFuture (JVM6+) • CompletableFuture (JVM8) • RxJava (JVM6+) 5

Slide 6

Slide 6 text

*Future(s) are not enough • Supporting single (scalar) values, • Future.get(period, TimeUnit) still blocks threads, • Composing is hard - leading to callback hell, • Complex flows required some kind of FSM, • Error handling is error-prone :) 6

Slide 7

Slide 7 text

https://github.com/ReactiveX/RxJava “RxJava – Reactive Extensions for the JVM – a library for composing asynchronous and event-based programs using observable sequences for the Java VM” 7

Slide 8

Slide 8 text

Buzzword alert: reactive! 8

Slide 9

Slide 9 text

Reactive manifesto v2 Reactive system has to be: 9 Responsive thus react to users demand Resilient thus react to errors and failure Elastic thus react to load Message-driven thus react to events and messages

Slide 10

Slide 10 text

Ok, but what’s reactive programming in this context? 10

Slide 11

Slide 11 text

Reactive programming • Wikipedia says: “Data flows and propagation of change”, • I prefer: “programming with asynchronous (in)finite data sequences” • Basically pushing data instead of pulling it 11

Slide 12

Slide 12 text

Reactive extensions • Implement reactive programming paradigm over (in)finite sequences of data, • Push data propagation: • Observer pattern on steroids, • Declarative (functional) API for composing sequences, • Non-opinionated about source of concurrency (schedulers, virtual time) 12

Slide 13

Slide 13 text

.NET was there first and everybody is into it now 13

Slide 14

Slide 14 text

.NET was there first • Version 1.0 released 17.11.2009, • Shipped with .NET 4.0 by default, • Version 2.0 released 15.08.2012, • With a support for “Portable Library” (.NET 4.5) • Reactive Extensions for JS released 17.03.2010 14

Slide 15

Slide 15 text

RxJava 1.0.x • Ported from .NET to JVM by Netflix, • Stable API release in November 2014, • After nearly two years of development, • Targeting Java (and Android), Scala, Groovy, JRuby, Kotlin and Clojure, • Last version 1.0.5 released 3 days ago 15

Slide 16

Slide 16 text

Observable vs Iterable vs Future 16 Scalar value Sequence Synchronous T Iterable Asynchronous* Future Observable * Observable is single-threaded by default

Slide 17

Slide 17 text

Observable is an ordered (serial) data sequence 17 * this is so called marble diagram (source: https://github.com/ReactiveX/RxJava/wiki/How-To-Use-RxJava)

Slide 18

Slide 18 text

RxJava API contract 18

Slide 19

Slide 19 text

Core types • Observer • Observable • OnSubscribe • Producer • Subscriber • Subscription • Operator • Scheduler • Subject 19

Slide 20

Slide 20 text

Observer contract • methods: • onNext(T) • onError(Throwable T) • onCompleted() • onError/onCompleted called exactly once 20

Slide 21

Slide 21 text

Observer example 21

Slide 22

Slide 22 text

Functional operators 22

Slide 23

Slide 23 text

Observable functional API 23 Operator class Source type Result type Anamorphic aka unfold T Observable Bind aka map Observable Observable Catamorphic aka fold or reduce Observable T http://en.wikipedia.org/wiki/Anamorphism, http://en.wikipedia.org/wiki/Catamorphism

Slide 24

Slide 24 text

Unfold operators aka “how to create observables” 24 Operator Description Observable.just(T value) Wraps plain value(s) into Observable Observable.range(int from, int to) Generates range sequence Observable.timer() Generates time-based sequence Observable.interval() Generates interval-based sequence Observable.create(OnSubscribe) Creates observable with delegate (most powerful) Observable.never() Empty sequence that never completes either way Observable.empty() Empty sequence that completes right away Observable.error(Throwable t) Empty sequence that completes with error

Slide 25

Slide 25 text

OnSubscribe 25

Slide 26

Slide 26 text

OnSubscribe contract • onNext() called from a single thread (synchronisation is not provided) • onCompleted() and onError() called exactly once, • Subscriber.isUnsubscribed() is checked prior to sending any notification • setProducer() is used to support reactive-pull back-pressure 26

Slide 27

Slide 27 text

Producer • Provided to support reactive pull back-pressure, • Observer can request n elements from producer, • If n == Long.MAX_VALUE back-pressure is disabled, • Still hard to use and do it right :( • But there is some work being done with FSM to better support back-pressure implementation 27

Slide 28

Slide 28 text

Producer example 28

Slide 29

Slide 29 text

Subscriber • Basically both Observer and Subscription, • Used in Operator for lifting Observables into Observables, • Maintains subscription list 29

Slide 30

Slide 30 text

Operator • Covers “bind” operator class for lifting Observables • Can preserve state in a scope of chained calls, • Should maintain subscriptions and unsubscribe requests, • It’s hard to write it right (composite subscriptions, back- pressure, cascading unsubscribe requests) 30

Slide 31

Slide 31 text

Operator 31

Slide 32

Slide 32 text

Transformer 32 What will be the result? ;)

Slide 33

Slide 33 text

Operators categories map and fold 33 Category Examples Combining join, startWith, merge, concat, zip… Conditional amb, skipUntil, skipWhile, takeUntil, takeWhile, defaultIfEmpty… Filtering filter, first, last, takeLast, skip, elementAt, sample, throttle, timeout, distinct, distinctUntilChange, ofType, ignoreElements… Aggregating concat, count, reduce, collect, toList, toMap, toSortedList… Transformational map, flatMap, switchMap, scan, groupBy, buffer, window… See more: http://reactivex.io/documentation/operators.html

Slide 34

Slide 34 text

Schedulers 34

Slide 35

Slide 35 text

Schedulers • Source of concurrency for Observables: • Observable can use them via observeOn/subscribeOn, • Schedules unit of work through Workers, • Workers represent serial execution of work. • Provides different processing strategies (Event Loop, Thread Pools, etc), • Couple provided out-of-the-box plus you can write your own 35

Slide 36

Slide 36 text

Schedulers 36 Name Description Schedulers.computation() Schedules computation bound work (ScheduledExecutorService with pool size = NCPU, LRU worker select strategy) Schedulers.immediate() Schedules work on current thread Schedulers.io() I/O bound work (ScheduledExecutorService with growing thread pool) Schedulers.trampoline() Queues work on the current thread Schedulers.newThread() Creates new thread for every unit of work Schedulers.test() Schedules work on scheduler supporting virtual time Schedulers.from(Executor e) Schedules work to be executed on provided executor

Slide 37

Slide 37 text

(subscribe|observe)On • Think of them this way: • subscribeOn - invocation of the subscription, • observeOn - observing of the notifications • Thus: • subscribeOn for background processing and warm-up 37

Slide 38

Slide 38 text

(subscribe|observe)On 38 What will be the result? ;)

Slide 39

Slide 39 text

Subjects 39

Slide 40

Slide 40 text

Subjects • Subject is a proxy between Observable and Subscriber • It can subscribe multiple observables • And emit items as an observable • Different Subject types has different properties 40

Slide 41

Slide 41 text

AsyncSubject

Slide 42

Slide 42 text

BehaviourSubject

Slide 43

Slide 43 text

PublishSubject

Slide 44

Slide 44 text

ReplaySubject

Slide 45

Slide 45 text

Back-pressure 45

Slide 46

Slide 46 text

Cold vs hot observables • Passive sequence is cold: • Producing notifications when requested • At rate Observer desires • Ideal for reactive pull model of back-pressure using Producer.request(n) • Active sequence is hot: • Producing notifications regardless of subscriptions: • Immediately when it is created • At rate Observer sometimes cannot handle, • Ideal for flow control strategies like buffering, windowing, throttling, onBackpressure* 46

Slide 47

Slide 47 text

Cold vs hot examples 47 Cold Hot Asynchronous requests (Observable.from) UI events (mouse clicks, movements) Created with OnSubscribe Timer events Subscriptions to queues Push pub/sub (broadcasts)

Slide 48

Slide 48 text

Dealing with back-pressure 48 https://github.com/ReactiveX/RxJava/wiki/Backpressure

Slide 49

Slide 49 text

onBackpressure* 49

Slide 50

Slide 50 text

Design considerations • Reactive Extensions are not a silver-bullet for dealing with concurrency: • Threading/synchronization concerns does not go away, • You can still block your threads (dead-lock), • Simple flows on top of RX and static sequences yields significant overhead, • Choosing right operators flow is a challenge, • You should avoid shared-state if possible (immutability FTW), • Debugging is quite hard (but there is “plugins” mechanism), • Understanding and using back-pressure well is harder :) 50

Slide 51

Slide 51 text

More reading • Free Rx.NET books: • Introduction to RX: http://www.introtorx.com/ • RX Design Guidelines: http://go.microsoft.com/fwlink/?LinkID=205219 • Reactive Extensions: http://reactivex.io • Interactive RX diagrams: http://rxmarbles.com • Reactive programming @ Netflix: http://techblog.netflix.com/2013/01/ reactive-programming-at-netflix.html 51

Slide 52

Slide 52 text

Interesting RX-enabled projects • https://github.com/Netflix/Hystrix • https://github.com/jersey/jersey • https://github.com/square/retrofit • https://github.com/ReactiveX/RxNetty • https://github.com/couchbase/couchbase-java-client • https://github.com/Netflix/ocelli • https://github.com/davidmoten/rtree 52

Slide 53

Slide 53 text

Thank you 53