Reactive programming with Rxjava

76
Christophe Marchal Reactive programming with RxJava

Transcript of Reactive programming with Rxjava

Page 1: Reactive programming with Rxjava

Christophe Marchal

Reactive programming with RxJava

Page 3: Reactive programming with Rxjava

MOTIVATION

Page 4: Reactive programming with Rxjava

Scaling

Moore’s law is delivering more cores but not faster cores

Page 5: Reactive programming with Rxjava

Amdahl’s law

Speedup limited by the sequential portion of the code

Page 6: Reactive programming with Rxjava

In other words, parallelize your

code to scale

Page 7: Reactive programming with Rxjava

I am not Netflix!

Page 8: Reactive programming with Rxjava

http://techblog.netflix.com/2016/09/zuul-2-netflix-journey-to-asynchronous.html

Multithreaded System Architecture

Page 9: Reactive programming with Rxjava

Efficient use of resources

● CPU efficient

● Memory efficient

● Hard Drive efficient

● Network efficient

Page 10: Reactive programming with Rxjava

Efficient use of threads

Page 11: Reactive programming with Rxjava

Non-Blocking architecture

Page 12: Reactive programming with Rxjava

http://techblog.netflix.com/2016/09/zuul-2-netflix-journey-to-asynchronous.html

Asynchronous and Non-Blocking System Architecture

Page 13: Reactive programming with Rxjava

Challenges

● listeners / callback● force functional code● exception handling● Everything becomes a

Stream

Page 14: Reactive programming with Rxjava

RxJava for the win!

Page 15: Reactive programming with Rxjava

Challenges

Page 16: Reactive programming with Rxjava

Erik Meijer

Origins

Page 17: Reactive programming with Rxjava

Reactive eXtension

Page 18: Reactive programming with Rxjava

Collection Future

Current vision

Page 19: Reactive programming with Rxjava

Observable: Stream of event

Reactive vision

Everything is an event

Page 20: Reactive programming with Rxjava

Observable: Stream of event

Observer

Reactive vision

Page 21: Reactive programming with Rxjava

Reactive vision

T getData()

One Item

synchronous

Page 22: Reactive programming with Rxjava

Reactive vision

Iterable<T> getData()T getData()

One Item Several Items

synchronous

Page 23: Reactive programming with Rxjava

Reactive vision

Iterable<T> getData()T getData()

Future<T> getData()

One Item Several Items

synchronous

Asynchronous

Page 24: Reactive programming with Rxjava

Reactive vision

Iterable<T> getData()

Observable<T> getData()

T getData()

Future<T> getData()

One Item Several Items

synchronous

Asynchronous

Page 25: Reactive programming with Rxjava

Pull vs Push

Iterable<T> getData() Observable<T> getData()

Pull

T next()throw Exception()

returns;

Push

onNext()onError()onComplete()

Page 28: Reactive programming with Rxjava

https://github.com/toff63/Sandbox/blob/master/java/rsjug-rx/rsjug-rx/src/main/java/rs/jug/rx/restclient/Application.java

Calling remote API

Observable from Future

Page 29: Reactive programming with Rxjava

https://github.com/toff63/Sandbox/blob/master/java/rsjug-rx/rsjug-rx/src/main/java/rs/jug/rx/restclient/Application.java

Calling remote API

Exception handling

Page 39: Reactive programming with Rxjava

Demo

Page 40: Reactive programming with Rxjava

Concurrency

Page 41: Reactive programming with Rxjava

Observable is sequential

Scheduling and Combining Observables enable Concurrency

Page 43: Reactive programming with Rxjava

Demo

Page 44: Reactive programming with Rxjava

Cold Stream vs Hot Stream

Hot Stream Cold Stream

no control on emission rate emits when requested

UI events, Metric events,

System events

DB query, Service request,

Downloading file

Page 45: Reactive programming with Rxjava

Cold Stream vs Hot Stream

Hot Stream Cold Stream

no control on emission rate emits when requested

UI events, Metric events,

System events

DB query, Service request,

Downloading file

Flow control Flow control & Back pressure

Page 46: Reactive programming with Rxjava

Flow Control

Page 47: Reactive programming with Rxjava

https://github.com/toff63/Sandbox/blob/master/java/rsjug-rx/rsjug-rx/src/main/java/rs/jug/rx/flowcontrol/Backpressure.java

Backpressure needed

Synchronous on same thread

Page 48: Reactive programming with Rxjava

https://github.com/toff63/Sandbox/blob/master/java/rsjug-rx/rsjug-rx/src/main/java/rs/jug/rx/flowcontrol/Backpressure.java

No backpressure needed

Asynchronous (queuing)

Page 49: Reactive programming with Rxjava

Block Operator

Hot Stream Cold Stream

Page 51: Reactive programming with Rxjava

Temporal Operators

Hot Stream

Page 52: Reactive programming with Rxjava

https://github.com/toff63/Sandbox/blob/master/java/rsjug-rx/rsjug-rx/src/main/java/rs/jug/rx/flowcontrol/Backpressure.java

Sample

9891040771910879031787798

Page 53: Reactive programming with Rxjava

https://github.com/toff63/Sandbox/blob/master/java/rsjug-rx/rsjug-rx/src/main/java/rs/jug/rx/flowcontrol/Backpressure.java

Throttle First

0118117118630717530662584575

Page 54: Reactive programming with Rxjava

Debounce

Page 56: Reactive programming with Rxjava

Buffer

Page 57: Reactive programming with Rxjava

https://github.com/toff63/Sandbox/blob/master/java/rsjug-rx/rsjug-rx/src/main/java/rs/jug/rx/flowcontrol/Backpressure.java

Buffer

[0, 1, 2, 3, 4, 5][6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20][21, 22, 23, 24, 25]

Page 58: Reactive programming with Rxjava

Window time

Page 59: Reactive programming with Rxjava

https://github.com/toff63/Sandbox/blob/master/java/rsjug-rx/rsjug-rx/src/main/java/rs/jug/rx/flowcontrol/Backpressure.java

28545333541675424446235

Window time

Page 60: Reactive programming with Rxjava

Reactive Stream

Page 61: Reactive programming with Rxjava

● Push when Consumer keeps up

● Pull when Consumer is slow

● Bound all queues

Maximize throughput

Page 62: Reactive programming with Rxjava

Reactive Stream: Consumer keeps up

Publisher Subscriber

As many as you can

Push

Page 63: Reactive programming with Rxjava

Reactive Stream: Consumer Starts buffering

Publisher Subscriber

As many as you can

Page 64: Reactive programming with Rxjava

Reactive Stream: Consumer Starts buffering

Publisher Subscriber

Give me 0

Give me 2

Pull

Page 65: Reactive programming with Rxjava

On backpressure buffer

Page 66: Reactive programming with Rxjava

On backpressure buffer Hot Stream

Hot Stream

Page 67: Reactive programming with Rxjava

On backpressure buffer

Scheduler

Hot Stream

Page 68: Reactive programming with Rxjava

On backpressure Drop

Page 69: Reactive programming with Rxjava

On backpressure buffer Hot Stream

Page 70: Reactive programming with Rxjava

And lots and lots of other operators

Page 71: Reactive programming with Rxjava

Rx Ports

Page 72: Reactive programming with Rxjava

● Observable API is complex

● Takes time to become fluent with Observable

● Hard to test !

● Debugging is harder as everything is asynchronous

● Stacktraces can be truncated due to scheduler

Drawbacks

Page 73: Reactive programming with Rxjava

Stacktrace example

18:42:59.487 [rx-request-processor-5-67] ERROR n.k.t.util.HttpContentInputStream - Error on serverio.netty.util.IllegalReferenceCountException: refCnt: 0 at io.netty.buffer.AbstractByteBuf.ensureAccessible(AbstractByteBuf.java:1178) ~[netty-buffer-4.0.27.Final.jar:4.0.27.Final] at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:848) ~[netty-buffer-4.0.27.Final.jar:4.0.27.Final] at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:841) ~[netty-buffer-4.0.27.Final.jar:4.0.27.Final] at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:831) ~[netty-buffer-4.0.27.Final.jar:4.0.27.Final] at netflix.karyon.transport.util.HttpContentInputStream$1.onNext(HttpContentInputStream.java:67) [karyon2-governator-2.3.0.jar:2.3.0] at netflix.karyon.transport.util.HttpContentInputStream$1.onNext(HttpContentInputStream.java:33) [karyon2-governator-2.3.0.jar:2.3.0] at rx.Observable$33.onNext(Observable.java:7480) [rxjava-1.0.10.jar:1.0.10] at rx.observers.SafeSubscriber.onNext(SafeSubscriber.java:130) [rxjava-1.0.10.jar:1.0.10] at io.reactivex.netty.protocol.http.UnicastContentSubject$AutoReleaseByteBufOperator$1.onNext(UnicastContentSubject.java:262) [rxnetty-0.4.9.jar:0.4.9] at rx.internal.operators.NotificationLite.accept(NotificationLite.java:150) [rxjava-1.0.10.jar:1.0.10] at rx.internal.operators.BufferUntilSubscriber.emit(BufferUntilSubscriber.java:151) [rxjava-1.0.10.jar:1.0.10] at rx.internal.operators.BufferUntilSubscriber.onNext(BufferUntilSubscriber.java:184) [rxjava-1.0.10.jar:1.0.10] at io.reactivex.netty.protocol.http.UnicastContentSubject.onNext(UnicastContentSubject.java:286) [rxnetty-0.4.9.jar:0.4.9] at io.reactivex.netty.protocol.http.server.ServerRequestResponseConverter.invokeContentOnNext(ServerRequestResponseConverter.java:193) [rxnetty-0.4.9.jar:0.4.9] at io.reactivex.netty.protocol.http.server.ServerRequestResponseConverter.channelRead(ServerRequestResponseConverter.java:129) [rxnetty-0.4.9.jar:0.4.9] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:339) [netty-transport-4.0.27.Final.jar:4.0.27.Final] at io.netty.channel.AbstractChannelHandlerContext.access$600(AbstractChannelHandlerContext.java:32) [netty-transport-4.0.27.Final.jar:4.0.27.Final] at io.netty.channel.AbstractChannelHandlerContext$7.run(AbstractChannelHandlerContext.java:329) [netty-transport-4.0.27.Final.jar:4.0.27.Final] at io.netty.util.concurrent.DefaultEventExecutor.run(DefaultEventExecutor.java:36) [netty-common-4.0.27.Final.jar:4.0.27.Final] at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:111) [netty-common-4.0.27.Final.jar:4.0.27.Final] at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:137) [netty-common-4.0.27.Final.jar:4.0.27.Final] at java.lang.Thread.run(Thread.java:745) [na:1.8.0_73]

Page 74: Reactive programming with Rxjava

Netflix experience migrating zuul

http://techblog.netflix.com/2016/09/zuul-2-netflix-journey-to-asynchronous.html

Page 76: Reactive programming with Rxjava

Christophe Marchal

Thank you !

Questions?