Top Banner
1 Mateusz Gajewski Solutions Architect @ Allegro Kraków Office Opening • February 2015 allegrotech.io, twitter: @allegrotechblog RxJava Reactive eXtensions for JVM
53
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: RxJava - introduction & design

1

Mateusz Gajewski Solutions Architect @ Allegro

Kraków Office Opening • February 2015

allegrotech.io, twitter: @allegrotechblog

RxJavaReactive eXtensions for JVM

Page 2: RxJava - introduction & design

But first, let me introduce myself…

2

Page 3: RxJava - introduction & design

Talk agenda• Problem statement

• Reactive programming concept

• Brief history of reactive extensions (RX)

• RxJava API contract

• Functional operators

• Schedulers

• Subjects

• Dealing with back-pressure3

Page 4: RxJava - introduction & design

Problem

4

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

Page 5: RxJava - introduction & design

Possible approaches

• Future<T>,

• Guava’s ListenableFuture<T> (JVM6+)

• CompletableFuture<T> (JVM8)

• RxJava (JVM6+)

5

Page 6: RxJava - introduction & design

*Future(s) are not enough

• Supporting single (scalar) values,

• Future<T>.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

Page 7: RxJava - introduction & design

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

Page 8: RxJava - introduction & design

Buzzword alert: reactive!

8

Page 9: RxJava - introduction & design

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

Page 10: RxJava - introduction & design

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

10

Page 11: RxJava - introduction & design

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

Page 12: RxJava - introduction & design

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

Page 13: RxJava - introduction & design

.NET was there firstand everybody is into it now

13

Page 14: RxJava - introduction & design

.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

Page 15: RxJava - introduction & design

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

Page 16: RxJava - introduction & design

Observable<T> vs Iterable<T> vs Future<T>

16

Scalar value Sequence

Synchronous T Iterable<T>

Asynchronous* Future<T> Observable<T>

* Observable is single-threaded by default

Page 17: RxJava - introduction & design

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)

Page 18: RxJava - introduction & design

RxJava API contract

18

Page 19: RxJava - introduction & design

Core types

• Observer<T>

• Observable<T>

• OnSubscribe<T>

• Producer

• Subscriber<T>

• Subscription

• Operator<T, R>

• Scheduler

• Subject<T>

19

Page 20: RxJava - introduction & design

Observer<T> contract

• methods:

• onNext(T)

• onError(Throwable T)

• onCompleted()

• onError/onCompleted called exactly once

20

Page 21: RxJava - introduction & design

Observer<T> example

21

Page 22: RxJava - introduction & design

Functional operators

22

Page 23: RxJava - introduction & design

Observable<T> functional API

23

Operator class Source type Result type

Anamorphic aka unfold

T Observable<T>

Bind aka map

Observable<T1> Observable<T2>

Catamorphic aka fold or reduce

Observable<T> T

http://en.wikipedia.org/wiki/Anamorphism, http://en.wikipedia.org/wiki/Catamorphism

Page 24: RxJava - introduction & design

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

Page 25: RxJava - introduction & design

OnSubscribe<T>

25

Page 26: RxJava - introduction & design

OnSubscribe<T> 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

Page 27: RxJava - introduction & design

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

Page 28: RxJava - introduction & design

Producer example

28

Page 29: RxJava - introduction & design

Subscriber<T>

• Basically both Observer<T> and Subscription,

• Used in Operator<T, R> for lifting Observables into Observables,

• Maintains subscription list

29

Page 30: RxJava - introduction & design

Operator<T, R>

• 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

Page 31: RxJava - introduction & design

Operator<T, R>

31

Page 32: RxJava - introduction & design

Transformer<T, R>

32

What will be the result? ;)

Page 33: RxJava - introduction & design

Operators categories map and fold

33

Category Examples

Combining join, startWith, merge, concat, zip…

Conditionalamb, skipUntil, skipWhile, takeUntil, takeWhile,

defaultIfEmpty…

Filteringfilter, 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

Page 34: RxJava - introduction & design

Schedulers

34

Page 35: RxJava - introduction & design

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

Page 36: RxJava - introduction & design

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

Page 37: RxJava - introduction & design

(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

Page 38: RxJava - introduction & design

(subscribe|observe)On

38

What will be the result? ;)

Page 39: RxJava - introduction & design

Subjects

39

Page 40: RxJava - introduction & design

Subjects

• Subject is a proxy between Observable<T> and Subscriber<T>

• It can subscribe multiple observables

• And emit items as an observable

• Different Subject types has different properties

40

Page 41: RxJava - introduction & design

AsyncSubject

Page 42: RxJava - introduction & design

BehaviourSubject

Page 43: RxJava - introduction & design

PublishSubject

Page 44: RxJava - introduction & design

ReplaySubject

Page 45: RxJava - introduction & design

Back-pressure

45

Page 46: RxJava - introduction & design

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

Page 47: RxJava - introduction & design

Cold vs hot examples

47

Cold Hot

Asynchronous requests (Observable.from)

UI events (mouse clicks, movements)

Created with OnSubscribe<T> Timer events

Subscriptions to queues Push pub/sub (broadcasts)

Page 48: RxJava - introduction & design

Dealing with back-pressure

48

https://github.com/ReactiveX/RxJava/wiki/Backpressure

Page 49: RxJava - introduction & design

onBackpressure*

49

Page 50: RxJava - introduction & design

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

Page 51: RxJava - introduction & design

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

Page 52: RxJava - introduction & design

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

Page 53: RxJava - introduction & design

Thank you

53