Designing for Distributed Systems with Reactor and Reactive Streams
-
Upload
stephane-maldini -
Category
Software
-
view
916 -
download
2
Transcript of Designing for Distributed Systems with Reactor and Reactive Streams
![Page 1: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/1.jpg)
Designing for Distributed Systems with Reactor and Reactive Streams
Stephane Maldini @smaldini
1
![Page 2: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/2.jpg)
WHY DISTRIBUTED SYSTEMS ARE THE NEW NORMAL ?
![Page 3: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/3.jpg)
SCALING MONOLITHIC APPS
Payments Adult
E-‐Learning Entertainment
Music Search
Payments Adult
E-‐Learning Entertainment
Music Search
Payments Adult
E-‐Learning Entertainment
Music Search
Payments Adult
E-‐Learning Entertainment
Music Search
![Page 4: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/4.jpg)
HOW YOU SHOULD SCALE ?
![Page 5: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/5.jpg)
HOW YOU SHOULD SCALE ?
Enternaiment
E-‐Learning
Payments
Adult
Music
Search
Requests
![Page 6: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/6.jpg)
![Page 7: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/7.jpg)
MICROSERVICES
![Page 8: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/8.jpg)
Dependencies ?
![Page 9: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/9.jpg)
The Speed Of Light
I wish I acted in Star Trek Teleporting anyone ?
![Page 10: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/10.jpg)
There’s latency between each remote call
![Page 11: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/11.jpg)
Let’s use asynchronous processing
There’s latency between each remote call
![Page 12: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/12.jpg)
Let’s use asynchronous processing
I shall not block incoming requests to keep serving
There’s latency between each remote call
![Page 13: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/13.jpg)
Let’s use asynchronous processing
I shall not block incoming requests to keep serving
Thread Executor !
There’s latency between each remote call
![Page 14: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/14.jpg)
private ExecutorService threadPool = Executors.newFixedThreadPool(2); final List<T> batches = new ArrayList<T>();
//…
Callable<T> t = new Callable<T>() {
public T run() { T result = callDatabase(); synchronized(batches) { batches.add(result); return result; } } };
Future<T> f = threadPool.submit(t); T result = f.get()
Vanilla background-‐processing
![Page 15: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/15.jpg)
private ExecutorService threadPool = Executors.newFixedThreadPool(2); final List<T> batches = new ArrayList<T>();
//…
Callable<T> t = new Callable<T>() {
public T run() { T result = callDatabase(); synchronized(batches) { batches.add(result); return result; } } };
Future<T> f = threadPool.submit(t); T result = f.get()
New Allocation By Request
Vanilla background-‐processing
![Page 16: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/16.jpg)
private ExecutorService threadPool = Executors.newFixedThreadPool(2); final List<T> batches = new ArrayList<T>();
//…
Callable<T> t = new Callable<T>() {
public T run() { T result = callDatabase(); synchronized(batches) { batches.add(result); return result; } } };
Future<T> f = threadPool.submit(t); T result = f.get()
New Allocation By Request
Queue-‐based message passing
Vanilla background-‐processing
![Page 17: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/17.jpg)
private ExecutorService threadPool = Executors.newFixedThreadPool(2); final List<T> batches = new ArrayList<T>();
//…
Callable<T> t = new Callable<T>() {
public T run() { T result = callDatabase(); synchronized(batches) { batches.add(result); return result; } } };
Future<T> f = threadPool.submit(t); T result = f.get()
New Allocation By Request
Queue-‐based message passing
Vanilla background-‐processing
What if this message fails ?
![Page 18: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/18.jpg)
private ExecutorService threadPool = Executors.newFixedThreadPool(2); final List<T> batches = new ArrayList<T>();
//…
Callable<T> t = new Callable<T>() {
public T run() { T result = callDatabase(); synchronized(batches) { batches.add(result); return result; } } };
Future<T> f = threadPool.submit(t); T result = f.get()
New Allocation By Request
Queue-‐based message passing
Vanilla background-‐processing
What if this message fails ?
censored
![Page 19: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/19.jpg)
Mixing latency with queue based handoff
http://ferd.ca/queues-don-t-fix-overload.html
![Page 20: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/20.jpg)
Mixing latency with queue based handoff
http://ferd.ca/queues-don-t-fix-overload.html
![Page 21: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/21.jpg)
Mixing latency with queue based handoff
http://ferd.ca/queues-don-t-fix-overload.html
![Page 22: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/22.jpg)
Queues must be bounded
![Page 23: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/23.jpg)
Passing message /w little overhead
Queues must be bounded
![Page 24: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/24.jpg)
Passing message /w little overhead
Tolerating some consuming rate difference
Queues must be bounded
![Page 25: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/25.jpg)
Passing message /w little overhead
Tolerating some consuming rate difference
Reactor !
Queues must be bounded
![Page 26: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/26.jpg)
Pre-‐allocating Slots -‐> The Ring Buffer
Publishing events to the right slot
dude!
![Page 27: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/27.jpg)
Re-‐using Threads too : Event Loop
I’m an event loop, consuming messages in the right order
![Page 28: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/28.jpg)
//RingBufferProcessor with 32 slots by default RingBufferProcessor<Integer> processor = RingBufferProcessor.create(); //Subscribe to receive events processor.subscribe( //Create a subscriber from a lambda/method ref SubscriberFactory.unbounded((data, s) ->
System.out.println(data) )
);
//Dispatch data asynchronously int i = 0; while(i++ < 100000) processor.onNext(i)
//Terminate the processor processor.shutdown();
![Page 29: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/29.jpg)
//a second subscriber to receive the same events in a distinct thread processor.subscribe( SubscriberFactory.unbounded((data, s) -> {
//a slow callback returning false when not interested in data anymore if(!sometimeSlow(data)){ //shutdown the consumer thread s.cancel();
}
}) );
![Page 30: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/30.jpg)
![Page 31: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/31.jpg)
Hold on ! The guy said bounded number of slots
![Page 32: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/32.jpg)
So we still block when the buffer is full!
Hold on ! The guy said bounded number of slots
![Page 33: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/33.jpg)
So we still block when the buffer is full!
…So why sending more requests
Hold on ! The guy said bounded number of slots
![Page 34: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/34.jpg)
So we still block when the buffer is full!
…So why sending more requests
Reactive Streams!
Hold on ! The guy said bounded number of slots
![Page 35: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/35.jpg)
What is defined in Reactive Streams
![Page 36: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/36.jpg)
Async non-blocking data sequence
What is defined in Reactive Streams
![Page 37: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/37.jpg)
Async non-blocking data sequence
Minimal resources requirement
What is defined in Reactive Streams
![Page 38: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/38.jpg)
Interoperable protocol (Threads, Nodes…)Async non-blocking data sequence
Minimal resources requirement
What is defined in Reactive Streams
![Page 39: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/39.jpg)
Async non-blocking flow-control
Interoperable protocol (Threads, Nodes…)Async non-blocking data sequence
Minimal resources requirement
What is defined in Reactive Streams
![Page 40: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/40.jpg)
Async non-blocking flow-control
Interoperable protocol (Threads, Nodes…)Async non-blocking data sequence
Minimal resources requirement
What is defined in Reactive Streams
![Page 41: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/41.jpg)
What is reactive flow control ?
![Page 42: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/42.jpg)
PUBLISHER
What is reactive flow control ?
![Page 43: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/43.jpg)
PUBLISHER
SUBSCRIBER
What is reactive flow control ?
![Page 44: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/44.jpg)
PUBLISHER
SUBSCRIBER
What is reactive flow control ?
SUBSCRIPTION
![Page 45: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/45.jpg)
PUBLISHER
SUBSCRIBER
Events
What is reactive flow control ?
SUBSCRIPTION
![Page 46: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/46.jpg)
PUBLISHER
SUBSCRIBER
Events
What is reactive flow control ?
SUBSCRIPTION
![Page 47: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/47.jpg)
PUBLISHER
SUBSCRIBER
Events
Demand
What is reactive flow control ?
SUBSCRIPTION
![Page 48: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/48.jpg)
All of that in 4 interfaces!
![Page 49: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/49.jpg)
And there’s a TCK to verify implementations
All of that in 4 interfaces!
![Page 50: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/50.jpg)
And there’s a TCK to verify implementations
No More Unwanted Requests
All of that in 4 interfaces!
![Page 51: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/51.jpg)
And there’s a TCK to verify implementations
No More Unwanted Requests
Need to propagate that demand upstream!
All of that in 4 interfaces!
![Page 52: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/52.jpg)
ccv
Doug Lea – SUNY Oswego
Some Smart Guys Involved
![Page 53: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/53.jpg)
RingBufferProcessor<Integer> processor = RingBufferProcessor.create(); //Subscribe to receive event […]
//Data access gated by a Publisher with backpressure PublisherFactory.forEach( sub -> { if(sub.context().hasNext()) sub.onNext(sub.context().readInt());
else sub.onComplete();
}, sub -> sqlContext(), context -> context.close()
) .subscribe(processor);
//Terminate the processor [..]
![Page 54: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/54.jpg)
RingBufferProcessor<Integer> processor = RingBufferProcessor.create(); //Subscribe to receive event […]
//Data access gated by a Publisher with backpressure PublisherFactory.forEach( sub -> { if(sub.context().hasNext()) sub.onNext(sub.context().readInt());
else sub.onComplete();
}, sub -> sqlContext(), context -> context.close()
) .subscribe(processor);
//Terminate the processor [..]Connect processor to this publisher and start requesting
![Page 55: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/55.jpg)
RingBufferProcessor<Integer> processor = RingBufferProcessor.create(); //Subscribe to receive event […]
//Data access gated by a Publisher with backpressure PublisherFactory.forEach( sub -> { if(sub.context().hasNext()) sub.onNext(sub.context().readInt());
else sub.onComplete();
}, sub -> sqlContext(), context -> context.close()
) .subscribe(processor);
//Terminate the processor [..]Connect processor to this publisher and start requesting
For the new connected processor, create some sql
context
![Page 56: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/56.jpg)
RingBufferProcessor<Integer> processor = RingBufferProcessor.create(); //Subscribe to receive event […]
//Data access gated by a Publisher with backpressure PublisherFactory.forEach( sub -> { if(sub.context().hasNext()) sub.onNext(sub.context().readInt());
else sub.onComplete();
}, sub -> sqlContext(), context -> context.close()
) .subscribe(processor);
//Terminate the processor [..]Connect processor to this publisher and start requesting
For the new connected processor, create some sql
context
Keep invoking this callback until there is no more
pending request
![Page 57: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/57.jpg)
What about combining multiple asynchronous calls
![Page 58: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/58.jpg)
And everything in a controlled fashion
What about combining multiple asynchronous calls
![Page 59: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/59.jpg)
And everything in a controlled fashion
Including Errors and Completion
What about combining multiple asynchronous calls
![Page 60: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/60.jpg)
And everything in a controlled fashion
Including Errors and Completion
Reactive Extensions !
What about combining multiple asynchronous calls
![Page 61: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/61.jpg)
FlatMap and Monads.. Nooooo Please No
24
Streams.just(‘doge’).flatMap{ name -> Streams.just(name) .observe{ println 'so wow' } .map{ 'much monad'} }.consume{ assert it == 'much monad' }
![Page 62: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/62.jpg)
FlatMap and Monads.. Nooooo Please No
24
Streams.just(‘doge’).flatMap{ name -> Streams.just(name) .observe{ println 'so wow' } .map{ 'much monad'} }.consume{ assert it == 'much monad' }
A publisher that only sends “doge” on request
![Page 63: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/63.jpg)
FlatMap and Monads.. Nooooo Please No
24
Streams.just(‘doge’).flatMap{ name -> Streams.just(name) .observe{ println 'so wow' } .map{ 'much monad'} }.consume{ assert it == 'much monad' }
A publisher that only sends “doge” on request
Sub-Stream definition
![Page 64: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/64.jpg)
FlatMap and Monads.. Nooooo Please No
24
Streams.just(‘doge’).flatMap{ name -> Streams.just(name) .observe{ println 'so wow' } .map{ 'much monad'} }.consume{ assert it == 'much monad' }
A publisher that only sends “doge” on request
Sub-Stream definition
All Sub-Streams are merged under a single sequence
![Page 65: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/65.jpg)
Scatter Gather and Fault Tolerance
25
Streams.merge( userService.filteredFind(“Rick"), // Stream of User userService.filteredFind(“Morty") // Stream of User ) .buffer() // Accumulate all results in a List .retryWhen( errors -‐> //Stream of Errors errors .zipWith(Streams.range(1,3), t -‐> t.getT2()) .flatMap( tries -‐> Streams.timer(tries) ) ) .consume(System.out::println);
![Page 66: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/66.jpg)
Scatter Gather and Fault Tolerance
25
Interleaved merge from 2 upstream publishers
Streams.merge( userService.filteredFind(“Rick"), // Stream of User userService.filteredFind(“Morty") // Stream of User ) .buffer() // Accumulate all results in a List .retryWhen( errors -‐> //Stream of Errors errors .zipWith(Streams.range(1,3), t -‐> t.getT2()) .flatMap( tries -‐> Streams.timer(tries) ) ) .consume(System.out::println);
![Page 67: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/67.jpg)
Scatter Gather and Fault Tolerance
25
Interleaved merge from 2 upstream publishers
Up to 3 tries
Streams.merge( userService.filteredFind(“Rick"), // Stream of User userService.filteredFind(“Morty") // Stream of User ) .buffer() // Accumulate all results in a List .retryWhen( errors -‐> //Stream of Errors errors .zipWith(Streams.range(1,3), t -‐> t.getT2()) .flatMap( tries -‐> Streams.timer(tries) ) ) .consume(System.out::println);
![Page 68: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/68.jpg)
Scatter Gather and Fault Tolerance
25
Interleaved merge from 2 upstream publishers
Up to 3 tries
All Sub-Streams are merged under a single sequence
Streams.merge( userService.filteredFind(“Rick"), // Stream of User userService.filteredFind(“Morty") // Stream of User ) .buffer() // Accumulate all results in a List .retryWhen( errors -‐> //Stream of Errors errors .zipWith(Streams.range(1,3), t -‐> t.getT2()) .flatMap( tries -‐> Streams.timer(tries) ) ) .consume(System.out::println);
![Page 69: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/69.jpg)
Scatter Gather and Fault Tolerance
25
Interleaved merge from 2 upstream publishers
Up to 3 tries
All Sub-Streams are merged under a single sequence
Streams.merge( userService.filteredFind(“Rick"), // Stream of User userService.filteredFind(“Morty") // Stream of User ) .buffer() // Accumulate all results in a List .retryWhen( errors -‐> //Stream of Errors errors .zipWith(Streams.range(1,3), t -‐> t.getT2()) .flatMap( tries -‐> Streams.timer(tries) ) ) .consume(System.out::println);
Delay retry
![Page 70: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/70.jpg)
REACTOR2™ = REACTOR + REACTIVE EXTENSIONS + REACTIVE STREAMS
![Page 71: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/71.jpg)
reactor-net
reactor-streams
reactor-bus
reactor-core
![Page 72: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/72.jpg)
reactor-net
reactor-streams
reactor-bus
reactor-core
Event Bus
Core Dispatchers & Processors
Streams and Promises
![Page 73: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/73.jpg)
reactor-net
reactor-streams
reactor-bus
reactor-coreFunctional artifacts
(SAM components, tuples, timers)
Event Bus
Core Dispatchers & Processors
Streams and Promises
![Page 74: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/74.jpg)
reactor-net
reactor-streams
reactor-bus
reactor-coreFunctional artifacts
(SAM components, tuples, timers)
Event Bus
Core Dispatchers & Processors
Streams and Promises
NetStreams [ Clients/Server ] [TCP, UDP, HTTP]
![Page 75: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/75.jpg)
reactor-net
reactor-streams
reactor-bus
reactor-coreFunctional artifacts
(SAM components, tuples, timers)
Event Bus
Core Dispatchers & Processors
Streams and Promises
NetStreams [ Clients/Server ] [TCP, UDP, HTTP]
Fast Data [buffer, codec]
![Page 76: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/76.jpg)
reactor-net
reactor-streams
reactor-bus
reactor-coreFunctional artifacts
(SAM components, tuples, timers)
Event Bus
Core Dispatchers & Processors
Streams and Promises
NetStreams [ Clients/Server ] [TCP, UDP, HTTP]
Fast Data [buffer, codec]
![Page 77: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/77.jpg)
reactor-net
reactor-streams
reactor-bus
reactor-coreFunctional artifacts
(SAM components, tuples, timers)
Event Bus
Core Dispatchers & Processors
Streams and Promises
NetStreams [ Clients/Server ] [TCP, UDP, HTTP]
Fast Data [buffer, codec]
![Page 78: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/78.jpg)
ASYNC IO ?
![Page 79: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/79.jpg)
![Page 80: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/80.jpg)
30
NetStreams.<String, String>httpServer(spec -‐> spec.codec(StandardCodecs.STRING_CODEC).listen(3000) ). ws("/", channel -‐> { System.out.println("Connected a websocket client: " + channel.remoteAddress());
return somePublisher. window(1000). flatMap(s -‐> channel.writeWith( s.
reduce(0f, (prev, trade) -‐> (trade.getPrice() + prev) / 2). map(Object::toString) )
); }). start(). await();
![Page 81: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/81.jpg)
30
NetStreams.<String, String>httpServer(spec -‐> spec.codec(StandardCodecs.STRING_CODEC).listen(3000) ). ws("/", channel -‐> { System.out.println("Connected a websocket client: " + channel.remoteAddress());
return somePublisher. window(1000). flatMap(s -‐> channel.writeWith( s.
reduce(0f, (prev, trade) -‐> (trade.getPrice() + prev) / 2). map(Object::toString) )
); }). start(). await();
Listen on port 3000 and convert bytes into String inbound/
outbound
![Page 82: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/82.jpg)
30
NetStreams.<String, String>httpServer(spec -‐> spec.codec(StandardCodecs.STRING_CODEC).listen(3000) ). ws("/", channel -‐> { System.out.println("Connected a websocket client: " + channel.remoteAddress());
return somePublisher. window(1000). flatMap(s -‐> channel.writeWith( s.
reduce(0f, (prev, trade) -‐> (trade.getPrice() + prev) / 2). map(Object::toString) )
); }). start(). await();
Listen on port 3000 and convert bytes into String inbound/
outbound
Upgrade clients to websocket on root URI
![Page 83: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/83.jpg)
30
NetStreams.<String, String>httpServer(spec -‐> spec.codec(StandardCodecs.STRING_CODEC).listen(3000) ). ws("/", channel -‐> { System.out.println("Connected a websocket client: " + channel.remoteAddress());
return somePublisher. window(1000). flatMap(s -‐> channel.writeWith( s.
reduce(0f, (prev, trade) -‐> (trade.getPrice() + prev) / 2). map(Object::toString) )
); }). start(). await();
Listen on port 3000 and convert bytes into String inbound/
outbound
Upgrade clients to websocket on root URI
Flush every 1000 data some data with writeWith + window
![Page 84: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/84.jpg)
30
NetStreams.<String, String>httpServer(spec -‐> spec.codec(StandardCodecs.STRING_CODEC).listen(3000) ). ws("/", channel -‐> { System.out.println("Connected a websocket client: " + channel.remoteAddress());
return somePublisher. window(1000). flatMap(s -‐> channel.writeWith( s.
reduce(0f, (prev, trade) -‐> (trade.getPrice() + prev) / 2). map(Object::toString) )
); }). start(). await();
Listen on port 3000 and convert bytes into String inbound/
outbound
Upgrade clients to websocket on root URI
Flush every 1000 data some data with writeWith + windowClose connection when
flatMap completes, which is when all Windows are done
![Page 85: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/85.jpg)
THE STATE OF THE ART
![Page 86: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/86.jpg)
Nowreactive-‐streams.1.0.0
50% guide complete : http://projectreactor.io/docs/reference
reactor-‐*.2.0.3.RELEASE -‐ 2.0.4 around the corner
reactor-‐*.2.1.0.BUILD-‐SNAPSHOT -‐ early access, no breaking changes
![Page 87: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/87.jpg)
Now
Initial Reactor 2 Support in : Spring Integration 4.2 Spring Messaging 4.2 Spring Boot 1.3 Spring XD 1.2 Grails 3.0
![Page 88: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/88.jpg)
After Now
Spring Integration DSL + Reactive Streams Dynamic Subscribers on Predefined Channels ! Best Tool for each job: SI for integrating Reactor for scaling up too fast to be true
![Page 89: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/89.jpg)
SI Java DSL + Reactive Stream Preview@Configuration @EnableIntegration public static class ContextConfiguration {
@Autowired private TaskScheduler taskScheduler;
@Bean public Publisher<Message<String>> reactiveFlow() { return IntegrationFlows .from(“inputChannel”) .split(String.class, p -> p.split(",")) .toReactiveStreamsPublisher(); }
@Bean public Publisher<Message<Integer>> pollableReactiveFlow() { return IntegrationFlows .from("inputChannel") .split(e -> e.get().getT2().setDelimiters(",")) .<String, Integer>transform(Integer::parseInt) .channel(Channels::queue) .toReactiveStreamsPublisher(this.taskScheduler); }
}
![Page 90: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/90.jpg)
After Now
Reactor + Spring Cloud • Annotation Driven FastData • Async IO : (proxy, client) • Circuit breaker, Bus, …
Reactor + Spring XD • Scale up any XD pipeline •Reactive Backpressure in XD
![Page 91: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/91.jpg)
37
@EnableReactorModule(concurrency = 5) public class PongMessageProcessor implements ReactiveProcessor<Message, Message> { @Override public void accept(Stream<Message> inputStream, ReactiveOutput<Message> output) { output.writeOutput( inputStream .map(simpleMap()) .observe(simpleMessage()) ); }
//… }
![Page 92: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/92.jpg)
37
@EnableReactorModule(concurrency = 5) public class PongMessageProcessor implements ReactiveProcessor<Message, Message> { @Override public void accept(Stream<Message> inputStream, ReactiveOutput<Message> output) { output.writeOutput( inputStream .map(simpleMap()) .observe(simpleMessage()) ); }
//… }
Split input XD channel in 5 threads ! With a blazing fast Processor
![Page 93: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/93.jpg)
37
@EnableReactorModule(concurrency = 5) public class PongMessageProcessor implements ReactiveProcessor<Message, Message> { @Override public void accept(Stream<Message> inputStream, ReactiveOutput<Message> output) { output.writeOutput( inputStream .map(simpleMap()) .observe(simpleMessage()) ); }
//… }
Split input XD channel in 5 threads ! With a blazing fast Processor
Register the sequence to write on the output channel after some operations
![Page 94: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/94.jpg)
After
<3 Spring 5 + Reactor & Reactive Streams <3
![Page 95: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/95.jpg)
After
Reactive IPC for the JVM <3 RxNetty + reactor-‐net <3
Reactor 2.0.3.+ already previews the concept and API flavor…
because REACTOR DOESN’T KNOW WAITING (LOL)
![Page 96: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/96.jpg)
Future ??
• RxJava 2.0 timeline (2016 and after?) • Thanks Interop, Reactive Extensions and Naming conventions, it can converge with reactor-‐streams
• https://github.com/ReactiveX/RxJava/wiki/Reactive-‐Streams
![Page 97: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/97.jpg)
Take-‐away
• Distributed System is the new cool and comes at some cost, two big ones are Latency and Failure Tolerance
• Asynchronous Processing and Error Handling by Design deal with these two problems -‐> Reactor, Reactive Extensions / Streams
• However to fully operate, Asynchronous Processing should be bounded proactively (stop-‐read) -‐> Reactive Streams
![Page 98: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/98.jpg)
![Page 99: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/99.jpg)
REACTIVE
![Page 100: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/100.jpg)
Extra
![Page 101: Designing for Distributed Systems with Reactor and Reactive Streams](https://reader030.fdocuments.us/reader030/viewer/2022032503/55bec1c0bb61eb0d7b8b4785/html5/thumbnails/101.jpg)
Take-‐away links
• http://reactive-‐streams.org • http://projectreactor.io • https://github.com/spring-‐projects/spring-‐integration-‐java-‐dsl/pull/31
• https://github.com/smaldini/spring-‐xd/tree/refresh-‐reactor-‐module/spring-‐xd-‐reactor/
• https://github.com/reactive-‐ipc/reactive-‐ipc-‐jvm • https://github.com/smaldini/ReactiveStreamsExamples