SlideShare a Scribd company logo
Declarative Concurrency
with Reactive Programming
Florian Stefan | #ebaytechtalk
Who am I?
§ Florian Stefan
§ fstefan@ebay.com | @f_s_t_e_f_a_n
§ Software Engineer at mobile.de (eBay Classifieds Group)
§ JVM-based web applications in cloud environment
Introduction
Why am I here?
§ C10K problem in IoT project
§ Spring, Play, Netty, Node.js
§ Legacy Systems / Microservice Architectures
Introduction
REACTIVE
Introduction
Reactive
Streams
Akka
Streams
ReactorRxJava 2
Back-
pressure
Marble
Diagrams
Function Composition
with Higher Order
Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
Reactive
Extensions
Introduction
Reactive
Streams
Akka
Streams
ReactorRxJava 2
Back-
pressure
Marble
Diagrams
Function Composition
with Higher Order
Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive
Extensions
Introduction
The Reactive Manifesto
Reactive Systems
responsive
resilient
event-driven
scalable
The Reactive Manifesto
Reactive Systems
responsive
resilient
event-driven
scalable
scalable
react to load
responsive
react to user
resilient
react to failure
event-driven
react to events
Reactive Programming
Reactive
Streams
Akka
Streams
ReactorRxJava 2
Back-
pressure
Marble
Diagrams
Function Composition
with Higher Order
Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive
Extensions
Reactive Extensions
§ Observer Pattern
§ Operators for transforming, composing,
scheduling, error-handling
§ Modeling event-based programs
§ Avoiding global state and side effects
Reactive Programming
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Marble Diagrams
Reactive Programming
Stream emitting 3 events,
followed by completion.
Stream emitting 3 events,
completed by error.
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Reactor
Reactive Programming
Stream emitting 3 events,
followed by completion.
Flux.create(emitter -> {
emitter.next(1);
emitter.next(2);
emitter.next(3);
emitter.complete();
});
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Reactor
Reactive Programming
Stream emitting 3 events,
followed by completion.
Stream emitting 3 events,
completed by error.
Flux.create(emitter -> {
emitter.next(1);
emitter.next(2);
emitter.next(3);
emitter.complete();
});
Flux.create(emitter -> {
emitter.next(1);
emitter.next(2);
emitter.next(3);
emitter.error(new RuntimeException());
});
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Subscribe
log.info("Before Flux.create()");
Flux<Integer> flux = Flux.create(emitter -> {
log.info("emitter.next({})", 1);
emitter.next(1);
log.info("emitter.complete()");
emitter.complete();
});
log.info("After Flux.create()");
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Reactive Programming
Subscribe
log.info("Before Flux.create()");
Flux<Integer> flux = Flux.create(emitter -> {
log.info("emitter.next({})", 1);
emitter.next(1);
log.info("emitter.complete()");
emitter.complete();
});
log.info("After Flux.create()");
[main] - Before Flux.create()
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Reactive Programming
Subscribe
log.info("Before Flux.create()");
Flux<Integer> flux = Flux.create(emitter -> {
log.info("emitter.next({})", 1);
emitter.next(1);
log.info("emitter.complete()");
emitter.complete();
});
log.info("After Flux.create()");
[main] - Before Flux.create()[main] - Before Flux.create()
[main] - After Flux.create()
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Reactive Programming
Subscribe
log.info("Before Flux.create()");
Flux<Integer> flux = Flux.create(emitter -> {
log.info("emitter.next({})", 1);
emitter.next(1);
log.info("emitter.complete()");
emitter.complete();
});
log.info("After Flux.create()");
log.info("Before Flux.subscribe()");
flux.subscribe(
next -> log.info("subscriber.onNext({})", next),
error -> log.info("subscriber.onError({})", error),
() -> log.info("subscriber.onComplete()")
);
log.info("After Flux.subscribe()");
Reactive Programming
Subscribe
log.info("Before Flux.create()");
Flux<Integer> flux = Flux.create(emitter -> {
log.info("emitter.next({})", 1);
emitter.next(1);
log.info("emitter.complete()");
emitter.complete();
});
log.info("After Flux.create()");
log.info("Before Flux.subscribe()");
flux.subscribe(
next -> log.info("subscriber.onNext({})", next),
error -> log.info("subscriber.onError({})", error),
() -> log.info("subscriber.onComplete()")
);
log.info("After Flux.subscribe()");
[main] - Before Flux.create()
Reactive Programming
Subscribe
log.info("Before Flux.create()");
Flux<Integer> flux = Flux.create(emitter -> {
log.info("emitter.next({})", 1);
emitter.next(1);
log.info("emitter.complete()");
emitter.complete();
});
log.info("After Flux.create()");
log.info("Before Flux.subscribe()");
flux.subscribe(
next -> log.info("subscriber.onNext({})", next),
error -> log.info("subscriber.onError({})", error),
() -> log.info("subscriber.onComplete()")
);
log.info("After Flux.subscribe()");
[main] - Before Flux.create()[main] - Before Flux.create()
[main] - After Flux.create()
Reactive Programming
Subscribe
log.info("Before Flux.create()");
Flux<Integer> flux = Flux.create(emitter -> {
log.info("emitter.next({})", 1);
emitter.next(1);
log.info("emitter.complete()");
emitter.complete();
});
log.info("After Flux.create()");
log.info("Before Flux.subscribe()");
flux.subscribe(
next -> log.info("subscriber.onNext({})", next),
error -> log.info("subscriber.onError({})", error),
() -> log.info("subscriber.onComplete()")
);
log.info("After Flux.subscribe()");
[main] - Before Flux.create()[main] - Before Flux.create()
[main] - After Flux.create()
[main] - Before Flux.create()
[main] - After Flux.create()
[main] - Before Flux.subscribe()
Reactive Programming
Subscribe
log.info("Before Flux.create()");
Flux<Integer> flux = Flux.create(emitter -> {
log.info("emitter.next({})", 1);
emitter.next(1);
log.info("emitter.complete()");
emitter.complete();
});
log.info("After Flux.create()");
log.info("Before Flux.subscribe()");
flux.subscribe(
next -> log.info("subscriber.onNext({})", next),
error -> log.info("subscriber.onError({})", error),
() -> log.info("subscriber.onComplete()")
);
log.info("After Flux.subscribe()");
[main] - Before Flux.create()[main] - Before Flux.create()
[main] - After Flux.create()
[main] - Before Flux.create()
[main] - After Flux.create()
[main] - Before Flux.subscribe()
[main] - Before Flux.create()
[main] - After Flux.create()
[main] - Before Flux.subscribe()
[main] - emitter.next(1)
Reactive Programming
Subscribe
log.info("Before Flux.create()");
Flux<Integer> flux = Flux.create(emitter -> {
log.info("emitter.next({})", 1);
emitter.next(1);
log.info("emitter.complete()");
emitter.complete();
});
log.info("After Flux.create()");
log.info("Before Flux.subscribe()");
flux.subscribe(
next -> log.info("subscriber.onNext({})", next),
error -> log.info("subscriber.onError({})", error),
() -> log.info("subscriber.onComplete()")
);
log.info("After Flux.subscribe()");
[main] - Before Flux.create()[main] - Before Flux.create()
[main] - After Flux.create()
[main] - Before Flux.create()
[main] - After Flux.create()
[main] - Before Flux.subscribe()
[main] - Before Flux.create()
[main] - After Flux.create()
[main] - Before Flux.subscribe()
[main] - emitter.next(1)
[main] - Before Flux.create()
[main] - After Flux.create()
[main] - Before Flux.subscribe()
[main] - emitter.next(1)
[main] - subscriber.onNext(1)
Reactive Programming
Subscribe
log.info("Before Flux.create()");
Flux<Integer> flux = Flux.create(emitter -> {
log.info("emitter.next({})", 1);
emitter.next(1);
log.info("emitter.complete()");
emitter.complete();
});
log.info("After Flux.create()");
log.info("Before Flux.subscribe()");
flux.subscribe(
next -> log.info("subscriber.onNext({})", next),
error -> log.info("subscriber.onError({})", error),
() -> log.info("subscriber.onComplete()")
);
log.info("After Flux.subscribe()");
[main] - Before Flux.create()[main] - Before Flux.create()
[main] - After Flux.create()
[main] - Before Flux.create()
[main] - After Flux.create()
[main] - Before Flux.subscribe()
[main] - Before Flux.create()
[main] - After Flux.create()
[main] - Before Flux.subscribe()
[main] - emitter.next(1)
[main] - Before Flux.create()
[main] - After Flux.create()
[main] - Before Flux.subscribe()
[main] - emitter.next(1)
[main] - subscriber.onNext(1)
[main] - Before Flux.create()
[main] - After Flux.create()
[main] - Before Flux.subscribe()
[main] - emitter.next(1)
[main] - subscriber.onNext(1)
[main] - emitter.complete()
Reactive Programming
Subscribe
log.info("Before Flux.create()");
Flux<Integer> flux = Flux.create(emitter -> {
log.info("emitter.next({})", 1);
emitter.next(1);
log.info("emitter.complete()");
emitter.complete();
});
log.info("After Flux.create()");
log.info("Before Flux.subscribe()");
flux.subscribe(
next -> log.info("subscriber.onNext({})", next),
error -> log.info("subscriber.onError({})", error),
() -> log.info("subscriber.onComplete()")
);
log.info("After Flux.subscribe()");
[main] - Before Flux.create()[main] - Before Flux.create()
[main] - After Flux.create()
[main] - Before Flux.create()
[main] - After Flux.create()
[main] - Before Flux.subscribe()
[main] - Before Flux.create()
[main] - After Flux.create()
[main] - Before Flux.subscribe()
[main] - emitter.next(1)
[main] - Before Flux.create()
[main] - After Flux.create()
[main] - Before Flux.subscribe()
[main] - emitter.next(1)
[main] - subscriber.onNext(1)
[main] - Before Flux.create()
[main] - After Flux.create()
[main] - Before Flux.subscribe()
[main] - emitter.next(1)
[main] - subscriber.onNext(1)
[main] - emitter.complete()
[main] - Before Flux.create()
[main] - After Flux.create()
[main] - Before Flux.subscribe()
[main] - emitter.next(1)
[main] - subscriber.onNext(1)
[main] - emitter.complete()
[main] - subscriber.onComplete()
Reactive Programming
Subscribe
log.info("Before Flux.create()");
Flux<Integer> flux = Flux.create(emitter -> {
log.info("emitter.next({})", 1);
emitter.next(1);
log.info("emitter.complete()");
emitter.complete();
});
log.info("After Flux.create()");
log.info("Before Flux.subscribe()");
flux.subscribe(
next -> log.info("subscriber.onNext({})", next),
error -> log.info("subscriber.onError({})", error),
() -> log.info("subscriber.onComplete()")
);
log.info("After Flux.subscribe()");
[main] - Before Flux.create()[main] - Before Flux.create()
[main] - After Flux.create()
[main] - Before Flux.create()
[main] - After Flux.create()
[main] - Before Flux.subscribe()
[main] - Before Flux.create()
[main] - After Flux.create()
[main] - Before Flux.subscribe()
[main] - emitter.next(1)
[main] - Before Flux.create()
[main] - After Flux.create()
[main] - Before Flux.subscribe()
[main] - emitter.next(1)
[main] - subscriber.onNext(1)
[main] - Before Flux.create()
[main] - After Flux.create()
[main] - Before Flux.subscribe()
[main] - emitter.next(1)
[main] - subscriber.onNext(1)
[main] - emitter.complete()
[main] - Before Flux.create()
[main] - After Flux.create()
[main] - Before Flux.subscribe()
[main] - emitter.next(1)
[main] - subscriber.onNext(1)
[main] - emitter.complete()
[main] - subscriber.onComplete()
[main] - Before Flux.create()
[main] - After Flux.create()
[main] - Before Flux.subscribe()
[main] - emitter.next(1)
[main] - subscriber.onNext(1)
[main] - emitter.complete()
[main] - subscriber.onComplete()
[main] - After Flux.subscribe()
Reactive Programming
Factory methods: fromIterable
https://raw.githubusercontent.com/reactor/reactor-core/v3.0.6.RELEASE/src/docs/marble/fromiterable.png
Reactive Programming
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Factory methods: fromIterable
public <T> Flux<T> fromIterable(Iterable<T> iterable) {
return Flux.create(emitter -> {
Iterator<T> iterator = iterable.iterator();
while (iterator.hasNext()) {
emitter.next(iterator.next());
}
emitter.complete();
});
}
Reactive Programming
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Factory methods: fromIterable
public <T> Flux<T> fromIterable(Iterable<T> iterable) {
return Flux.create(emitter -> {
Iterator<T> iterator = iterable.iterator();
while (iterator.hasNext()) {
emitter.next(iterator.next());
}
emitter.complete();
});
}
naive implementation
Reactive Programming
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Factory methods: fromCallable
https://raw.githubusercontent.com/reactor/reactor-core/v3.0.6.RELEASE/src/docs/marble/fromcallable.png
Mono<User> maybeUser = Mono
.fromCallable(() -> loadUser(cwid))
Reactive Programming
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
StepVerifier
Flux<String> flux = Flux.fromIterable(cwids).take(5);
Reactive Programming
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
StepVerifier
Flux<String> flux = Flux.fromIterable(cwids).take(5);
Reactive Programming
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
StepVerifier.create(flux)
StepVerifier
Flux<String> flux = Flux.fromIterable(cwids).take(5);
Reactive Programming
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
StepVerifier.create(flux)
.expectSubscription()
StepVerifier
Flux<String> flux = Flux.fromIterable(cwids).take(5);
Reactive Programming
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
StepVerifier.create(flux)
.expectNext(cwids.get(0))
.expectSubscription()
StepVerifier
Flux<String> flux = Flux.fromIterable(cwids).take(5);
Reactive Programming
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
StepVerifier.create(flux)
.expectNext(cwids.get(0))
.expectNext(cwids.get(1))
.expectSubscription()
StepVerifier
Flux<String> flux = Flux.fromIterable(cwids).take(5);
Reactive Programming
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
StepVerifier.create(flux)
.expectNext(cwids.get(0))
.expectNext(cwids.get(1))
.expectNext(cwids.get(2), cwids.get(3), cwids.get(4))
.expectSubscription()
StepVerifier
Flux<String> flux = Flux.fromIterable(cwids).take(5);
Reactive Programming
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
StepVerifier.create(flux)
.expectNext(cwids.get(0))
.expectNext(cwids.get(1))
.expectNext(cwids.get(2), cwids.get(3), cwids.get(4))
.expectComplete()
.expectSubscription()
StepVerifier
Flux<String> flux = Flux.fromIterable(cwids).take(5);
Reactive Programming
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
StepVerifier.create(flux)
.expectNext(cwids.get(0))
.expectNext(cwids.get(1))
.expectNext(cwids.get(2), cwids.get(3), cwids.get(4))
.expectComplete()
.verify();
.expectSubscription()
Operators: take
Reactive Programming
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
https://raw.githubusercontent.com/reactor/reactor-core/master/src/docs/marble/take.png
Flux.fromIterable(cwids)
.take(3)
...
Operators: map
Reactive Programming
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
https://raw.githubusercontent.com/reactor/reactor-core/master/src/docs/marble/map.png
Flux.fromIterable(cwids)
.map(cwid -> loadUser(cwid))
...
Operators: flatMap
Reactive Programming
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
https://raw.githubusercontent.com/reactor/reactor-core/master/src/docs/marble/flatmap.png
Flux.fromIterable(cwids)
.flatMap(cwid -> loadUserAsMono(cwid))
...
Operators: flatMap
Reactive Programming
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Flux<User> users = Flux
.fromIterable(cwids)
.flatMap(cwid -> loadUserAsMono(cwid));
Operators: flatMap
Reactive Programming
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Flux<User> users = Flux
.fromIterable(cwids)
.flatMap(cwid -> loadUserAsMono(cwid));
private Mono<User> loadUserAsMono(String cwid) {
return Mono.fromCallable(() -> loadUser(cwid));
}
Operators: flatMap
Reactive Programming
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Flux<User> users = Flux
.fromIterable(cwids)
.flatMap(cwid -> loadUserAsMono(cwid));
private Mono<User> loadUserAsMono(String cwid) {
return Mono.fromCallable(() -> loadUser(cwid));
}
StepVerifier.create(users)
Operators: flatMap
Reactive Programming
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Flux<User> users = Flux
.fromIterable(cwids)
.flatMap(cwid -> loadUserAsMono(cwid));
private Mono<User> loadUserAsMono(String cwid) {
return Mono.fromCallable(() -> loadUser(cwid));
}
StepVerifier.create(users)
.expectNextMatches(hasCwid(cwids.get(0)))
Operators: flatMap
Reactive Programming
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Flux<User> users = Flux
.fromIterable(cwids)
.flatMap(cwid -> loadUserAsMono(cwid));
private Mono<User> loadUserAsMono(String cwid) {
return Mono.fromCallable(() -> loadUser(cwid));
}
StepVerifier.create(users)
.expectNextMatches(hasCwid(cwids.get(0)))
.expectNextMatches(hasCwid(cwids.get(1)))
Operators: flatMap
Reactive Programming
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Flux<User> users = Flux
.fromIterable(cwids)
.flatMap(cwid -> loadUserAsMono(cwid));
private Mono<User> loadUserAsMono(String cwid) {
return Mono.fromCallable(() -> loadUser(cwid));
}
StepVerifier.create(users)
.expectNextMatches(hasCwid(cwids.get(0)))
.expectNextMatches(hasCwid(cwids.get(1)))
.expectNextMatches(hasCwid(cwids.get(2)))
Operators: flatMap
Reactive Programming
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Flux<User> users = Flux
.fromIterable(cwids)
.flatMap(cwid -> loadUserAsMono(cwid));
private Mono<User> loadUserAsMono(String cwid) {
return Mono.fromCallable(() -> loadUser(cwid));
}
StepVerifier.create(users)
.expectNextMatches(hasCwid(cwids.get(0)))
.expectNextMatches(hasCwid(cwids.get(1)))
.expectNextMatches(hasCwid(cwids.get(2)))
...
.verifyComplete();
Operators: flatMap
Reactive Programming
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Flux<User> users = Flux
.fromIterable(cwids)
.flatMap(cwid -> loadUserAsMono(cwid));
?
private Mono<User> loadUserAsMono(String cwid) {
return Mono.fromCallable(() -> loadUser(cwid));
}
StepVerifier.create(users)
.expectNextMatches(hasCwid(cwids.get(0)))
.expectNextMatches(hasCwid(cwids.get(1)))
.expectNextMatches(hasCwid(cwids.get(2)))
...
.verifyComplete();
SubscribeOn
log.info("Before Flux.create()");
Flux<Integer> flux = Flux.create(emitter -> {
log.info("emitter.next({})", 1);
emitter.next(1);
log.info("emitter.complete()");
emitter.complete();
}) ;
log.info("After Flux.create()");
log.info("Before Flux.subscribe()");
flux.subscribe(
next -> log.info("subscriber.onNext({})", next),
error -> log.info("subscriber.onError({})", error),
() -> log.info("subscriber.onComplete()")
);
log.info("After Flux.subscribe()");
Declarative Concurrency
SubscribeOn
log.info("Before Flux.create()");
Flux<Integer> flux = Flux.create(emitter -> {
log.info("emitter.next({})", 1);
emitter.next(1);
log.info("emitter.complete()");
emitter.complete();
}) ;
log.info("After Flux.create()");
log.info("Before Flux.subscribe()");
flux.subscribe(
next -> log.info("subscriber.onNext({})", next),
error -> log.info("subscriber.onError({})", error),
() -> log.info("subscriber.onComplete()")
);
log.info("After Flux.subscribe()");
Declarative Concurrency
.subscribeOn(Schedulers.parallel())
SubscribeOn
log.info("Before Flux.create()");
Flux<Integer> flux = Flux.create(emitter -> {
log.info("emitter.next({})", 1);
emitter.next(1);
log.info("emitter.complete()");
emitter.complete();
}) ;
log.info("After Flux.create()");
log.info("Before Flux.subscribe()");
flux.subscribe(
next -> log.info("subscriber.onNext({})", next),
error -> log.info("subscriber.onError({})", error),
() -> log.info("subscriber.onComplete()")
);
log.info("After Flux.subscribe()");
[main] - Before Flux.create()
Declarative Concurrency
.subscribeOn(Schedulers.parallel())
SubscribeOn
log.info("Before Flux.create()");
Flux<Integer> flux = Flux.create(emitter -> {
log.info("emitter.next({})", 1);
emitter.next(1);
log.info("emitter.complete()");
emitter.complete();
}) ;
log.info("After Flux.create()");
log.info("Before Flux.subscribe()");
flux.subscribe(
next -> log.info("subscriber.onNext({})", next),
error -> log.info("subscriber.onError({})", error),
() -> log.info("subscriber.onComplete()")
);
log.info("After Flux.subscribe()");
[main] - Before Flux.create()
Declarative Concurrency
[main] - After Flux.create()
.subscribeOn(Schedulers.parallel())
SubscribeOn
log.info("Before Flux.create()");
Flux<Integer> flux = Flux.create(emitter -> {
log.info("emitter.next({})", 1);
emitter.next(1);
log.info("emitter.complete()");
emitter.complete();
}) ;
log.info("After Flux.create()");
log.info("Before Flux.subscribe()");
flux.subscribe(
next -> log.info("subscriber.onNext({})", next),
error -> log.info("subscriber.onError({})", error),
() -> log.info("subscriber.onComplete()")
);
log.info("After Flux.subscribe()");
[main] - Before Flux.create()
Declarative Concurrency
[main] - After Flux.create()
[main] - Before Flux.subscribe()
.subscribeOn(Schedulers.parallel())
SubscribeOn
log.info("Before Flux.create()");
Flux<Integer> flux = Flux.create(emitter -> {
log.info("emitter.next({})", 1);
emitter.next(1);
log.info("emitter.complete()");
emitter.complete();
}) ;
log.info("After Flux.create()");
log.info("Before Flux.subscribe()");
flux.subscribe(
next -> log.info("subscriber.onNext({})", next),
error -> log.info("subscriber.onError({})", error),
() -> log.info("subscriber.onComplete()")
);
log.info("After Flux.subscribe()");
[main] - Before Flux.create()
Declarative Concurrency
[main] - After Flux.create()
[main] - Before Flux.subscribe()
[main] - After Flux.subscribe()
.subscribeOn(Schedulers.parallel())
SubscribeOn
log.info("Before Flux.create()");
Flux<Integer> flux = Flux.create(emitter -> {
log.info("emitter.next({})", 1);
emitter.next(1);
log.info("emitter.complete()");
emitter.complete();
}) ;
log.info("After Flux.create()");
log.info("Before Flux.subscribe()");
flux.subscribe(
next -> log.info("subscriber.onNext({})", next),
error -> log.info("subscriber.onError({})", error),
() -> log.info("subscriber.onComplete()")
);
log.info("After Flux.subscribe()");
[main] - Before Flux.create()
Declarative Concurrency
[main] - After Flux.create()
[main] - Before Flux.subscribe()
[main] - After Flux.subscribe()
[par1] - emitter.next(1).subscribeOn(Schedulers.parallel())
SubscribeOn
log.info("Before Flux.create()");
Flux<Integer> flux = Flux.create(emitter -> {
log.info("emitter.next({})", 1);
emitter.next(1);
log.info("emitter.complete()");
emitter.complete();
}) ;
log.info("After Flux.create()");
log.info("Before Flux.subscribe()");
flux.subscribe(
next -> log.info("subscriber.onNext({})", next),
error -> log.info("subscriber.onError({})", error),
() -> log.info("subscriber.onComplete()")
);
log.info("After Flux.subscribe()");
[main] - Before Flux.create()
Declarative Concurrency
[main] - After Flux.create()
[main] - Before Flux.subscribe()
[main] - After Flux.subscribe()
[par1] - emitter.next(1)
[par1] - subscriber.onNext(1)
.subscribeOn(Schedulers.parallel())
SubscribeOn
log.info("Before Flux.create()");
Flux<Integer> flux = Flux.create(emitter -> {
log.info("emitter.next({})", 1);
emitter.next(1);
log.info("emitter.complete()");
emitter.complete();
}) ;
log.info("After Flux.create()");
log.info("Before Flux.subscribe()");
flux.subscribe(
next -> log.info("subscriber.onNext({})", next),
error -> log.info("subscriber.onError({})", error),
() -> log.info("subscriber.onComplete()")
);
log.info("After Flux.subscribe()");
[main] - Before Flux.create()
Declarative Concurrency
[main] - After Flux.create()
[main] - Before Flux.subscribe()
[main] - After Flux.subscribe()
[par1] - emitter.next(1)
[par1] - subscriber.onNext(1)
[par1] - emitter.complete()
.subscribeOn(Schedulers.parallel())
SubscribeOn
log.info("Before Flux.create()");
Flux<Integer> flux = Flux.create(emitter -> {
log.info("emitter.next({})", 1);
emitter.next(1);
log.info("emitter.complete()");
emitter.complete();
}) ;
log.info("After Flux.create()");
log.info("Before Flux.subscribe()");
flux.subscribe(
next -> log.info("subscriber.onNext({})", next),
error -> log.info("subscriber.onError({})", error),
() -> log.info("subscriber.onComplete()")
);
log.info("After Flux.subscribe()");
[main] - Before Flux.create()
[par1] – subscriber.onComplete()
Declarative Concurrency
[main] - After Flux.create()
[main] - Before Flux.subscribe()
[main] - After Flux.subscribe()
[par1] - emitter.next(1)
[par1] - subscriber.onNext(1)
[par1] - emitter.complete()
.subscribeOn(Schedulers.parallel())
SubscribeOn Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
log.info("Before Flux.fromIterable()");
Flux<User> users = Flux
.fromIterable(cwids)
.flatMap(cwid -> Mono
.fromCallable(() -> loadUser(cwid)))
;
Declarative Concurrency
SubscribeOn Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
log.info("Before Flux.fromIterable()");
Flux<User> users = Flux
.fromIterable(cwids)
.flatMap(cwid -> Mono
.fromCallable(() -> loadUser(cwid)))
;
Declarative Concurrency
.subscribeOn(Schedulers.parallel())
SubscribeOn Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
log.info("Before Flux.fromIterable()");
Flux<User> users = Flux
.fromIterable(cwids)
.flatMap(cwid -> Mono
.fromCallable(() -> loadUser(cwid)))
;
Declarative Concurrency
.subscribeOn(Schedulers.parallel())
[main] - Before Flux.fromIterable()
SubscribeOn Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
log.info("Before Flux.fromIterable()");
Flux<User> users = Flux
.fromIterable(cwids)
.flatMap(cwid -> Mono
.fromCallable(() -> loadUser(cwid)))
;
Declarative Concurrency
[par1] - loadUser(7896c6eb)
.subscribeOn(Schedulers.parallel())
[main] - Before Flux.fromIterable()
SubscribeOn Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
log.info("Before Flux.fromIterable()");
Flux<User> users = Flux
.fromIterable(cwids)
.flatMap(cwid -> Mono
.fromCallable(() -> loadUser(cwid)))
;
Declarative Concurrency
[par1] - loadUser(7896c6eb)
[par1] - loadUser(75ad9445).subscribeOn(Schedulers.parallel())
[main] - Before Flux.fromIterable()
SubscribeOn Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
log.info("Before Flux.fromIterable()");
Flux<User> users = Flux
.fromIterable(cwids)
.flatMap(cwid -> Mono
.fromCallable(() -> loadUser(cwid)))
;
Declarative Concurrency
[par1] - loadUser(7896c6eb)
[par1] - loadUser(75ad9445)
[par1] - loadUser(e2d4c51d)
.subscribeOn(Schedulers.parallel())
[main] - Before Flux.fromIterable()
SubscribeOn Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
log.info("Before Flux.fromIterable()");
Flux<User> users = Flux
.fromIterable(cwids)
.flatMap(cwid -> Mono
.fromCallable(() -> loadUser(cwid)))
;
Declarative Concurrency
[par1] - loadUser(7896c6eb)
[par1] - loadUser(75ad9445)
[par1] - loadUser(e2d4c51d)
.subscribeOn(Schedulers.parallel())
StepVerifier.create(users)
[main] - Before Flux.fromIterable()
SubscribeOn Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
log.info("Before Flux.fromIterable()");
Flux<User> users = Flux
.fromIterable(cwids)
.flatMap(cwid -> Mono
.fromCallable(() -> loadUser(cwid)))
;
Declarative Concurrency
[par1] - loadUser(7896c6eb)
[par1] - loadUser(75ad9445)
[par1] - loadUser(e2d4c51d)
.subscribeOn(Schedulers.parallel())
StepVerifier.create(users)
.expectNextMatches(hasCwid(cwids.get(0)))
[main] - Before Flux.fromIterable()
SubscribeOn Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
log.info("Before Flux.fromIterable()");
Flux<User> users = Flux
.fromIterable(cwids)
.flatMap(cwid -> Mono
.fromCallable(() -> loadUser(cwid)))
;
Declarative Concurrency
[par1] - loadUser(7896c6eb)
[par1] - loadUser(75ad9445)
[par1] - loadUser(e2d4c51d)
.subscribeOn(Schedulers.parallel())
StepVerifier.create(users)
.expectNextMatches(hasCwid(cwids.get(0)))
.expectNextMatches(hasCwid(cwids.get(1)))
[main] - Before Flux.fromIterable()
SubscribeOn Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
log.info("Before Flux.fromIterable()");
Flux<User> users = Flux
.fromIterable(cwids)
.flatMap(cwid -> Mono
.fromCallable(() -> loadUser(cwid)))
;
Declarative Concurrency
[par1] - loadUser(7896c6eb)
[par1] - loadUser(75ad9445)
[par1] - loadUser(e2d4c51d)
.subscribeOn(Schedulers.parallel())
StepVerifier.create(users)
.expectNextMatches(hasCwid(cwids.get(0)))
.expectNextMatches(hasCwid(cwids.get(1)))
.expectNextMatches(hasCwid(cwids.get(2)))
[main] - Before Flux.fromIterable()
SubscribeOn Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
log.info("Before Flux.fromIterable()");
Flux<User> users = Flux
.fromIterable(cwids)
.flatMap(cwid -> Mono
.fromCallable(() -> loadUser(cwid)))
;
Declarative Concurrency
[par1] - loadUser(7896c6eb)
[par1] - loadUser(75ad9445)
[par1] - loadUser(e2d4c51d)
.subscribeOn(Schedulers.parallel())
StepVerifier.create(users)
.expectNextMatches(hasCwid(cwids.get(0)))
.expectNextMatches(hasCwid(cwids.get(1)))
.expectNextMatches(hasCwid(cwids.get(2)))
...
.verifyComplete();
[main] - Before Flux.fromIterable()
SubscribeOn Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
log.info("Before Flux.fromIterable()");
Flux<User> users = Flux
.fromIterable(cwids)
.flatMap(cwid -> Mono
.fromCallable(() -> loadUser(cwid)))
;
Declarative Concurrency
[par1] - loadUser(7896c6eb)
[par1] - loadUser(75ad9445)
[par1] - loadUser(e2d4c51d)
.subscribeOn(Schedulers.parallel())
StepVerifier.create(users)
.expectNextMatches(hasCwid(cwids.get(0)))
.expectNextMatches(hasCwid(cwids.get(1)))
.expectNextMatches(hasCwid(cwids.get(2)))
...
.verifyComplete();
✓
[main] - Before Flux.fromIterable()
SubscribeOn Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
log.info("Before Flux.fromIterable()");
Flux<User> users = Flux
.fromIterable(cwids)
.flatMap(cwid -> Mono
.fromCallable(() -> loadUser(cwid)))
;
Declarative Concurrency
[par1] - loadUser(7896c6eb)
[par1] - loadUser(75ad9445)
[par1] - loadUser(e2d4c51d)
.subscribeOn(Schedulers.parallel())
StepVerifier.create(users)
.expectNextMatches(hasCwid(cwids.get(0)))
.expectNextMatches(hasCwid(cwids.get(1)))
.expectNextMatches(hasCwid(cwids.get(2)))
...
.verifyComplete();
✓
[main] - Before Flux.fromIterable()
✗
SubscribeOn Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
log.info("Before Flux.fromIterable()");
Flux<User> users = Flux
.fromIterable(cwids)
.flatMap(cwid -> Mono
.fromCallable(() -> loadUser(cwid))
);
Declarative Concurrency
SubscribeOn Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
log.info("Before Flux.fromIterable()");
Flux<User> users = Flux
.fromIterable(cwids)
.flatMap(cwid -> Mono
.fromCallable(() -> loadUser(cwid))
);
Declarative Concurrency
.subscribeOn(Schedulers.parallel())
SubscribeOn Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
log.info("Before Flux.fromIterable()");
Flux<User> users = Flux
.fromIterable(cwids)
.flatMap(cwid -> Mono
.fromCallable(() -> loadUser(cwid))
);
Declarative Concurrency
.subscribeOn(Schedulers.parallel())
[main] - Before Flux.fromIterable()
SubscribeOn Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
log.info("Before Flux.fromIterable()");
Flux<User> users = Flux
.fromIterable(cwids)
.flatMap(cwid -> Mono
.fromCallable(() -> loadUser(cwid))
);
Declarative Concurrency
[par1] - loadUser(7896c6eb)
.subscribeOn(Schedulers.parallel())
[main] - Before Flux.fromIterable()
SubscribeOn Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
log.info("Before Flux.fromIterable()");
Flux<User> users = Flux
.fromIterable(cwids)
.flatMap(cwid -> Mono
.fromCallable(() -> loadUser(cwid))
);
Declarative Concurrency
[par1] - loadUser(7896c6eb)
[par2] - loadUser(75ad9445).subscribeOn(Schedulers.parallel())
[main] - Before Flux.fromIterable()
SubscribeOn Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
log.info("Before Flux.fromIterable()");
Flux<User> users = Flux
.fromIterable(cwids)
.flatMap(cwid -> Mono
.fromCallable(() -> loadUser(cwid))
);
Declarative Concurrency
[par1] - loadUser(7896c6eb)
[par2] - loadUser(75ad9445)
[par3] - loadUser(e2d4c51d)
.subscribeOn(Schedulers.parallel())
[main] - Before Flux.fromIterable()
SubscribeOn Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
log.info("Before Flux.fromIterable()");
Flux<User> users = Flux
.fromIterable(cwids)
.flatMap(cwid -> Mono
.fromCallable(() -> loadUser(cwid))
);
Declarative Concurrency
[par1] - loadUser(7896c6eb)
[par2] - loadUser(75ad9445)
[par3] - loadUser(e2d4c51d)
.subscribeOn(Schedulers.parallel())
StepVerifier.create(users)
.expectNextMatches(hasCwid(cwids.get(0)))
.expectNextMatches(hasCwid(cwids.get(1)))
.expectNextMatches(hasCwid(cwids.get(2)))
...
.verifyComplete();
[main] - Before Flux.fromIterable()
SubscribeOn Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
log.info("Before Flux.fromIterable()");
Flux<User> users = Flux
.fromIterable(cwids)
.flatMap(cwid -> Mono
.fromCallable(() -> loadUser(cwid))
);
Declarative Concurrency
[par1] - loadUser(7896c6eb)
[par2] - loadUser(75ad9445)
[par3] - loadUser(e2d4c51d)
.subscribeOn(Schedulers.parallel())
StepVerifier.create(users)
.expectNextMatches(hasCwid(cwids.get(0)))
.expectNextMatches(hasCwid(cwids.get(1)))
.expectNextMatches(hasCwid(cwids.get(2)))
...
.verifyComplete();
✗
[main] - Before Flux.fromIterable()
SubscribeOn Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
log.info("Before Flux.fromIterable()");
Flux<User> users = Flux
.fromIterable(cwids)
.flatMap(cwid -> Mono
.fromCallable(() -> loadUser(cwid))
);
Declarative Concurrency
[par1] - loadUser(7896c6eb)
[par2] - loadUser(75ad9445)
[par3] - loadUser(e2d4c51d)
.subscribeOn(Schedulers.parallel())
StepVerifier.create(users)
.expectNextMatches(hasCwid(cwids.get(0)))
.expectNextMatches(hasCwid(cwids.get(1)))
.expectNextMatches(hasCwid(cwids.get(2)))
...
.verifyComplete();
✗
[main] - Before Flux.fromIterable()
✓
Virtual Time Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
log.info("Before Flux.fromIterable()");
Flux<User> users = Flux
.fromIterable(cwids)
.flatMap(cwid -> Mono
.fromCallable(() -> loadUser(cwid))
.subscribeOn(Schedulers.parallel()));
StepVerifier
Declarative Concurrency
Virtual Time Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
log.info("Before Flux.fromIterable()");
Flux<User> users = Flux
.fromIterable(cwids)
.flatMap(cwid -> Mono
.fromCallable(() -> loadUser(cwid))
.subscribeOn(Schedulers.parallel()));
StepVerifier
Declarative Concurrency
.withVirtualTime(users)
Virtual Time Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
log.info("Before Flux.fromIterable()");
Flux<User> users = Flux
.fromIterable(cwids)
.flatMap(cwid -> Mono
.fromCallable(() -> loadUser(cwid))
.subscribeOn(Schedulers.parallel()));
StepVerifier
Declarative Concurrency
.withVirtualTime(users)
.thenAwait()
Virtual Time Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
log.info("Before Flux.fromIterable()");
Flux<User> users = Flux
.fromIterable(cwids)
.flatMap(cwid -> Mono
.fromCallable(() -> loadUser(cwid))
.subscribeOn(Schedulers.parallel()));
StepVerifier
Declarative Concurrency
.withVirtualTime(users)
.thenAwait()
.expectNextMatches(hasCwid(cwids.get(0)))
Virtual Time Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
log.info("Before Flux.fromIterable()");
Flux<User> users = Flux
.fromIterable(cwids)
.flatMap(cwid -> Mono
.fromCallable(() -> loadUser(cwid))
.subscribeOn(Schedulers.parallel()));
StepVerifier
Declarative Concurrency
.withVirtualTime(users)
.thenAwait()
.expectNextMatches(hasCwid(cwids.get(0)))
.expectNextMatches(hasCwid(cwids.get(1)))
Virtual Time Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
log.info("Before Flux.fromIterable()");
Flux<User> users = Flux
.fromIterable(cwids)
.flatMap(cwid -> Mono
.fromCallable(() -> loadUser(cwid))
.subscribeOn(Schedulers.parallel()));
StepVerifier
Declarative Concurrency
.withVirtualTime(users)
.thenAwait()
.expectNextMatches(hasCwid(cwids.get(0)))
.expectNextMatches(hasCwid(cwids.get(1)))
.expectNextMatches(hasCwid(cwids.get(2)))
Virtual Time Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
log.info("Before Flux.fromIterable()");
Flux<User> users = Flux
.fromIterable(cwids)
.flatMap(cwid -> Mono
.fromCallable(() -> loadUser(cwid))
.subscribeOn(Schedulers.parallel()));
StepVerifier
Declarative Concurrency
.withVirtualTime(users)
.thenAwait()
.expectNextMatches(hasCwid(cwids.get(0)))
.expectNextMatches(hasCwid(cwids.get(1)))
.expectNextMatches(hasCwid(cwids.get(2)))
...
.verifyComplete();
Virtual Time Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
log.info("Before Flux.fromIterable()");
Flux<User> users = Flux
.fromIterable(cwids)
.flatMap(cwid -> Mono
.fromCallable(() -> loadUser(cwid))
.subscribeOn(Schedulers.parallel()));
StepVerifier
Declarative Concurrency
Supplier< > () ->
.withVirtualTime(users)
.thenAwait()
.expectNextMatches(hasCwid(cwids.get(0)))
.expectNextMatches(hasCwid(cwids.get(1)))
.expectNextMatches(hasCwid(cwids.get(2)))
...
.verifyComplete();
Virtual Time Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
log.info("Before Flux.fromIterable()");
Flux<User> users = Flux
.fromIterable(cwids)
.flatMap(cwid -> Mono
.fromCallable(() -> loadUser(cwid))
.subscribeOn(Schedulers.parallel()));
StepVerifier
Declarative Concurrency
Supplier< > () ->
.withVirtualTime(users)
.thenAwait()
.expectNextMatches(hasCwid(cwids.get(0)))
.expectNextMatches(hasCwid(cwids.get(1)))
.expectNextMatches(hasCwid(cwids.get(2)))
...
.verifyComplete();
✓
Let‘s go wild ...
Declarative Concurrency
Flux
.fromIterable(cwids)
.flatMap(cwid -> Mono.fromCallable(() -> loadUser(cwid))
.subscribeOn(Schedulers.parallel()));
Let‘s go wild ...
Declarative Concurrency
Flux
.fromIterable(cwids)
.flatMap(cwid -> Mono.fromCallable(() -> loadUser(cwid))
.subscribeOn(Schedulers.parallel()));
CONCURRENCY
Let‘s go wild ...
Declarative Concurrency
Flux
.fromIterable(cwids)
.flatMap(cwid -> Mono.fromCallable(() -> loadUser(cwid))
.subscribeOn(Schedulers.parallel()));
.timeout(Duration.ofMillis(250), Schedulers.single())
TIMEOUT
CONCURRENCY
Let‘s go wild ...
Declarative Concurrency
Flux
.fromIterable(cwids)
.flatMap(cwid -> Mono.fromCallable(() -> loadUser(cwid))
.subscribeOn(Schedulers.parallel()));
.timeout(Duration.ofMillis(250), Schedulers.single())
.retry(numRetries)
TIMEOUT
RETRY
CONCURRENCY
Let‘s go wild ...
Declarative Concurrency
Flux
.fromIterable(cwids)
.flatMap(cwid -> Mono.fromCallable(() -> loadUser(cwid))
.subscribeOn(Schedulers.parallel()));
.timeout(Duration.ofMillis(250), Schedulers.single())
.retryWhen(errors -> errors.zipWith(Flux.range(0, MAX_VALUE), (err, idx) -> {
if (idx < numRetries) {
return Mono.just(err).delayElement(withExponentialBackoff(idx));
} else {
return Mono.error(err);
}
}).flatMap(Function.identity()))
TIMEOUT
RETRY WITH EXPONENTIAL BACKOFF
CONCURRENCY
Let‘s go wild ...
Declarative Concurrency
Flux
.fromIterable(cwids)
.flatMap(cwid -> Mono.fromCallable(() -> loadUser(cwid))
.subscribeOn(Schedulers.parallel()));
.timeout(Duration.ofMillis(250), Schedulers.single())
.retryWhen(errors -> errors.zipWith(Flux.range(0, MAX_VALUE), (err, idx) -> {
if (idx < numRetries) {
return Mono.just(err).delayElement(withExponentialBackoff(idx));
} else {
return Mono.error(err);
}
}).flatMap(Function.identity()))
long ms = (long) Math.pow(10, idx);
return Duration.ofMillis(ms);
TIMEOUT
RETRY WITH EXPONENTIAL BACKOFF
CONCURRENCY
Let‘s go wild ...
Declarative Concurrency
Flux
.fromIterable(cwids)
.flatMap(cwid -> Mono.fromCallable(() -> loadUser(cwid))
.subscribeOn(Schedulers.parallel()));
.timeout(Duration.ofMillis(250), Schedulers.single())
.retryWhen(errors -> errors.zipWith(Flux.range(0, MAX_VALUE), (err, idx) -> {
if (idx < numRetries) {
return Mono.just(err).delayElement(withExponentialBackoff(idx));
} else {
return Mono.error(err);
}
}).flatMap(Function.identity()))
TIMEOUT
RETRY WITH EXPONENTIAL BACKOFF
CONCURRENCY
Let‘s go wild ...
Declarative Concurrency
Flux
.fromIterable(cwids)
.flatMap(cwid -> Mono.fromCallable(() -> loadUser(cwid))
.subscribeOn(Schedulers.parallel()));
.timeout(Duration.ofMillis(250), Schedulers.single())
.retryWhen(errors -> errors.zipWith(Flux.range(0, MAX_VALUE), (err, idx) -> {
if (idx < numRetries) {
return Mono.just(err).delayElement(withExponentialBackoff(idx));
} else {
return Mono.error(err);
}
}).flatMap(Function.identity()))
.map(Either::<String, User>right)
.otherwiseReturn(left(cwid))
Flux<Either<String, User>> users =
TIMEOUT
RETRY WITH EXPONENTIAL BACKOFF
ERROR HANDLINGCONCURRENCY
Backpressure
Reactive
Streams
Akka
Streams
ReactorRxJava 2
Back-
pressure
Marble
Diagrams
Function Composition
with Higher Order
Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive
Extensions
Reactive Streams
§ Flow API in Java 9: java.util.concurrent.Flow
§ Standard for asynchronous stream processing
§ Pivotal, Lightbend, Netflix, Oracle, Red Hat and others
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Backpressure
Reactive Streams
public class Flow {
interface Processor<T, R> { ... }
interface Publisher<T> { ... }
interface Subscriber<T> { ... }
interface Subscription { ... }
}
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Backpressure
Subscriber
Pushing
Backpressure
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Publisher
Subscriber
Pushing
Backpressure
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Publisher
Subscriber
Pushing
Backpressure
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Publisher
Subscriber
Pushing
Backpressure
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Publisher
Subscriber
Pushing
Backpressure
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Publisher
Subscriber
Pushing
Backpressure
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Publisher
Subscriber
Pushing
Backpressure
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Publisher
Subscriber
Pushing
Backpressure
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Publisher
Pushing
Backpressure
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
ExecutorService executorService = new ThreadPoolExecutor(
10,
10,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(500)
);
Pushing
Backpressure
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
List<Future<User>> eventualUsers = cwids.stream()
.map(cwid -> executorService.submit(() -> loadUser(cwid)))
.collect(toList());
List<User> users = eventualUsers.stream()
.map(eventualUser -> {
try { return eventualUser.get(); }
catch (Exception e) { throw new RuntimeException(e); }
})
.collect(toList());
Pushing
Backpressure
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
java.util.concurrent.RejectedExecutionException:
Task java.util.concurrent.FutureTask@632ceb35 rejected
from java.util.concurrent.ThreadPoolExecutor@1c93f6e1[
Running, pool size = 10, active threads = 10,
queued tasks = 500, completed tasks = 0
]
Subscriber
Pulling and Pushing
Backpressure
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Publisher
Subscription
Subscriber
request(3)
Pulling and Pushing
Backpressure
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Publisher
Subscription
Subscriber
Pulling and Pushing
Backpressure
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Publisher
Subscription
Subscriber
Pulling and Pushing
Backpressure
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Publisher
Subscription
Subscriber
Pulling and Pushing
Backpressure
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Publisher
Subscription
Subscriber
Pulling and Pushing
Backpressure
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Publisher
Subscription
Subscriber
Pulling and Pushing
Backpressure
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Publisher
Subscription
Subscriber
Pulling and Pushing
Backpressure
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Publisher
Subscription
Subscriber
Pulling and Pushing
Backpressure
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Publisher
Subscription
Subscriber
Pulling and Pushing
Backpressure
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Publisher
Subscription
request(2)
Subscriber
Pulling and Pushing
Backpressure
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Publisher
Subscription
Subscriber
Pulling and Pushing
Backpressure
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Publisher
Subscription
Subscriber
Pulling and Pushing
Backpressure
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Publisher
Subscription
Subscriber
Pulling and Pushing
Backpressure
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Publisher
Subscription
Subscriber
Pulling and Pushing
Backpressure
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
Publisher
Subscription
List<User> users = Flux.fromIterable(cwids)
.flatMap(cwid -> Mono
.fromCallable(() -> loadUser(cwid))
.subscribeOn(Schedulers.fromExecutor(executorService)))
.collectList()
.block();
Pulling and Pushing
Backpressure
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
class FluxIterable<T> {
Iterable<? extends T> iterable;
FluxIterable(Iterable<? extends T> iterable) {
this.iterable = iterable;
}
// more than 500 lines of code
}
Pulling and Pushing: fromIterable
Backpressure
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
naive implementation
of fromIterable does
not enable backpressure
!
Pulling and Pushing: flatMap
Backpressure
Reactive
Streams
Akka Streams
ReactorRxJava 2
Backpressure
Marble Diagrams
Function Composition with Higher
Order Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive Extensions
https://raw.githubusercontent.com/reactor/reactor-core/v3.0.6.RELEASE/src/docs/marble/flatmapc.png
Conclusion
Reactive
Streams
Akka
Streams
ReactorRxJava 2
Back-
pressure
Marble
Diagrams
Function Composition
with Higher Order
Functions
Functional
Programming
Declarative
Programming
REACTIVE
PROGRAMMING
REACTIVE
SYSTEMS
Reactive
Extensions
What‘s more?
§ Concurrency with publishOn and ParallelFlux
§ Declarative Error Handling
§ Logging and Monitoring
§ Cold Streams vs. Hot Streams
§ C10K and Non-blocking IO
§ Reactive Streams in the Web
Conclusion
DISCUSS!
Conclusion

More Related Content

PDF
Project Reactor Now and Tomorrow
PDF
Being Functional on Reactive Streams with Spring Reactor
PDF
M|18 Architectural Overview: MariaDB MaxScale
PDF
ProxySQL and the Tricks Up Its Sleeve - Percona Live 2022.pdf
PDF
HandsOn ProxySQL Tutorial - PLSC18
PDF
MySQL InnoDB Cluster - Group Replication
PDF
MySQL GTID Concepts, Implementation and troubleshooting
PPTX
Introduction to gRPC
Project Reactor Now and Tomorrow
Being Functional on Reactive Streams with Spring Reactor
M|18 Architectural Overview: MariaDB MaxScale
ProxySQL and the Tricks Up Its Sleeve - Percona Live 2022.pdf
HandsOn ProxySQL Tutorial - PLSC18
MySQL InnoDB Cluster - Group Replication
MySQL GTID Concepts, Implementation and troubleshooting
Introduction to gRPC

What's hot (20)

PDF
MariaDB MaxScale
PDF
Getting started with MQTT - Virtual IoT Meetup presentation
PPT
Design Pattern For C# Part 1
PDF
PostgreSQL High Availability in a Containerized World
PDF
PostgreSQL Replication High Availability Methods
PDF
Galera Cluster for MySQL vs MySQL (NDB) Cluster: A High Level Comparison
PDF
MySQL InnoDB Cluster: High Availability Made Easy!
PDF
MySQL-InnoDB
PDF
SQL Transactions - What they are good for and how they work
PDF
[2019] 200만 동접 게임을 위한 MySQL 샤딩
PDF
Solid NodeJS with TypeScript, Jest & NestJS
PDF
Introduction to Spring WebFlux #jsug #sf_a1
PDF
OpenStack DevStack Install - 2부 (Multi-nodes)
PDF
Taking Security Groups to Ludicrous Speed with OVS (OpenStack Summit 2015)
PDF
Introduction to gRPC
PDF
Action Jackson! Effective JSON processing in Spring Boot Applications
PDF
All about Zookeeper and ClickHouse Keeper.pdf
PDF
Understanding PostgreSQL LW Locks
PDF
MySQL/MariaDB Proxy Software Test
PDF
Networking in Java with NIO and Netty
MariaDB MaxScale
Getting started with MQTT - Virtual IoT Meetup presentation
Design Pattern For C# Part 1
PostgreSQL High Availability in a Containerized World
PostgreSQL Replication High Availability Methods
Galera Cluster for MySQL vs MySQL (NDB) Cluster: A High Level Comparison
MySQL InnoDB Cluster: High Availability Made Easy!
MySQL-InnoDB
SQL Transactions - What they are good for and how they work
[2019] 200만 동접 게임을 위한 MySQL 샤딩
Solid NodeJS with TypeScript, Jest & NestJS
Introduction to Spring WebFlux #jsug #sf_a1
OpenStack DevStack Install - 2부 (Multi-nodes)
Taking Security Groups to Ludicrous Speed with OVS (OpenStack Summit 2015)
Introduction to gRPC
Action Jackson! Effective JSON processing in Spring Boot Applications
All about Zookeeper and ClickHouse Keeper.pdf
Understanding PostgreSQL LW Locks
MySQL/MariaDB Proxy Software Test
Networking in Java with NIO and Netty
Ad

Similar to Declarative Concurrency with Reactive Programming (20)

PDF
Reactive Programming in Java and Spring Framework 5
PDF
Reactive systems
PDF
Reactive Programming in Java by Mario Fusco - Codemotion Rome 2015
PDF
Reactive Programming for a demanding world: building event-driven and respons...
PDF
Reactive Applications in Java
PPTX
Mario Fusco - Reactive programming in Java - Codemotion Milan 2017
PDF
Reactive Everywhere
PDF
Next generation of frontend architectures
PDF
Buy ebook Functional Reactive Programming 1st Edition Stephen Blackheath chea...
PDF
Embracing Reactive Streams with Java 9 and Spring 5
PPT
Reactive programming with examples
PDF
Reactive mesh
PPTX
Reactive solutions using java 9 and spring reactor
PPTX
Reactive programming
PDF
Reactive programming with Pivotal's reactor
PDF
ReactiveX
PDF
Reactive Card Magic: Understanding Spring WebFlux and Project Reactor
PDF
I have a stream - Insights in Reactive Programming - Jan Carsten Lohmuller - ...
PDF
Workshop: Event-sourced system through Reactive Streams
PPTX
Workshop: Event-sourced system through Reactive Streams
Reactive Programming in Java and Spring Framework 5
Reactive systems
Reactive Programming in Java by Mario Fusco - Codemotion Rome 2015
Reactive Programming for a demanding world: building event-driven and respons...
Reactive Applications in Java
Mario Fusco - Reactive programming in Java - Codemotion Milan 2017
Reactive Everywhere
Next generation of frontend architectures
Buy ebook Functional Reactive Programming 1st Edition Stephen Blackheath chea...
Embracing Reactive Streams with Java 9 and Spring 5
Reactive programming with examples
Reactive mesh
Reactive solutions using java 9 and spring reactor
Reactive programming
Reactive programming with Pivotal's reactor
ReactiveX
Reactive Card Magic: Understanding Spring WebFlux and Project Reactor
I have a stream - Insights in Reactive Programming - Jan Carsten Lohmuller - ...
Workshop: Event-sourced system through Reactive Streams
Workshop: Event-sourced system through Reactive Streams
Ad

Recently uploaded (20)

PDF
gpt5_lecture_notes_comprehensive_20250812015547.pdf
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PPTX
Big Data Technologies - Introduction.pptx
PDF
Empathic Computing: Creating Shared Understanding
PDF
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
PDF
NewMind AI Weekly Chronicles - August'25-Week II
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PPTX
Cloud computing and distributed systems.
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
A comparative analysis of optical character recognition models for extracting...
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
Electronic commerce courselecture one. Pdf
PDF
Assigned Numbers - 2025 - Bluetooth® Document
PPTX
MYSQL Presentation for SQL database connectivity
PPTX
sap open course for s4hana steps from ECC to s4
PDF
Network Security Unit 5.pdf for BCA BBA.
gpt5_lecture_notes_comprehensive_20250812015547.pdf
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
Big Data Technologies - Introduction.pptx
Empathic Computing: Creating Shared Understanding
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
NewMind AI Weekly Chronicles - August'25-Week II
The Rise and Fall of 3GPP – Time for a Sabbatical?
Cloud computing and distributed systems.
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Dropbox Q2 2025 Financial Results & Investor Presentation
A comparative analysis of optical character recognition models for extracting...
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Advanced methodologies resolving dimensionality complications for autism neur...
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Unlocking AI with Model Context Protocol (MCP)
Electronic commerce courselecture one. Pdf
Assigned Numbers - 2025 - Bluetooth® Document
MYSQL Presentation for SQL database connectivity
sap open course for s4hana steps from ECC to s4
Network Security Unit 5.pdf for BCA BBA.

Declarative Concurrency with Reactive Programming

  • 1. Declarative Concurrency with Reactive Programming Florian Stefan | #ebaytechtalk
  • 2. Who am I? § Florian Stefan § [email protected] | @f_s_t_e_f_a_n § Software Engineer at mobile.de (eBay Classifieds Group) § JVM-based web applications in cloud environment Introduction
  • 3. Why am I here? § C10K problem in IoT project § Spring, Play, Netty, Node.js § Legacy Systems / Microservice Architectures Introduction
  • 5. Reactive Streams Akka Streams ReactorRxJava 2 Back- pressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING Reactive Extensions Introduction
  • 6. Reactive Streams Akka Streams ReactorRxJava 2 Back- pressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions Introduction
  • 7. The Reactive Manifesto Reactive Systems responsive resilient event-driven scalable
  • 8. The Reactive Manifesto Reactive Systems responsive resilient event-driven scalable scalable react to load responsive react to user resilient react to failure event-driven react to events
  • 9. Reactive Programming Reactive Streams Akka Streams ReactorRxJava 2 Back- pressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions
  • 10. Reactive Extensions § Observer Pattern § Operators for transforming, composing, scheduling, error-handling § Modeling event-based programs § Avoiding global state and side effects Reactive Programming Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions
  • 11. Marble Diagrams Reactive Programming Stream emitting 3 events, followed by completion. Stream emitting 3 events, completed by error. Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions
  • 12. Reactor Reactive Programming Stream emitting 3 events, followed by completion. Flux.create(emitter -> { emitter.next(1); emitter.next(2); emitter.next(3); emitter.complete(); }); Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions
  • 13. Reactor Reactive Programming Stream emitting 3 events, followed by completion. Stream emitting 3 events, completed by error. Flux.create(emitter -> { emitter.next(1); emitter.next(2); emitter.next(3); emitter.complete(); }); Flux.create(emitter -> { emitter.next(1); emitter.next(2); emitter.next(3); emitter.error(new RuntimeException()); }); Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions
  • 14. Subscribe log.info("Before Flux.create()"); Flux<Integer> flux = Flux.create(emitter -> { log.info("emitter.next({})", 1); emitter.next(1); log.info("emitter.complete()"); emitter.complete(); }); log.info("After Flux.create()"); Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions Reactive Programming
  • 15. Subscribe log.info("Before Flux.create()"); Flux<Integer> flux = Flux.create(emitter -> { log.info("emitter.next({})", 1); emitter.next(1); log.info("emitter.complete()"); emitter.complete(); }); log.info("After Flux.create()"); [main] - Before Flux.create() Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions Reactive Programming
  • 16. Subscribe log.info("Before Flux.create()"); Flux<Integer> flux = Flux.create(emitter -> { log.info("emitter.next({})", 1); emitter.next(1); log.info("emitter.complete()"); emitter.complete(); }); log.info("After Flux.create()"); [main] - Before Flux.create()[main] - Before Flux.create() [main] - After Flux.create() Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions Reactive Programming
  • 17. Subscribe log.info("Before Flux.create()"); Flux<Integer> flux = Flux.create(emitter -> { log.info("emitter.next({})", 1); emitter.next(1); log.info("emitter.complete()"); emitter.complete(); }); log.info("After Flux.create()"); log.info("Before Flux.subscribe()"); flux.subscribe( next -> log.info("subscriber.onNext({})", next), error -> log.info("subscriber.onError({})", error), () -> log.info("subscriber.onComplete()") ); log.info("After Flux.subscribe()"); Reactive Programming
  • 18. Subscribe log.info("Before Flux.create()"); Flux<Integer> flux = Flux.create(emitter -> { log.info("emitter.next({})", 1); emitter.next(1); log.info("emitter.complete()"); emitter.complete(); }); log.info("After Flux.create()"); log.info("Before Flux.subscribe()"); flux.subscribe( next -> log.info("subscriber.onNext({})", next), error -> log.info("subscriber.onError({})", error), () -> log.info("subscriber.onComplete()") ); log.info("After Flux.subscribe()"); [main] - Before Flux.create() Reactive Programming
  • 19. Subscribe log.info("Before Flux.create()"); Flux<Integer> flux = Flux.create(emitter -> { log.info("emitter.next({})", 1); emitter.next(1); log.info("emitter.complete()"); emitter.complete(); }); log.info("After Flux.create()"); log.info("Before Flux.subscribe()"); flux.subscribe( next -> log.info("subscriber.onNext({})", next), error -> log.info("subscriber.onError({})", error), () -> log.info("subscriber.onComplete()") ); log.info("After Flux.subscribe()"); [main] - Before Flux.create()[main] - Before Flux.create() [main] - After Flux.create() Reactive Programming
  • 20. Subscribe log.info("Before Flux.create()"); Flux<Integer> flux = Flux.create(emitter -> { log.info("emitter.next({})", 1); emitter.next(1); log.info("emitter.complete()"); emitter.complete(); }); log.info("After Flux.create()"); log.info("Before Flux.subscribe()"); flux.subscribe( next -> log.info("subscriber.onNext({})", next), error -> log.info("subscriber.onError({})", error), () -> log.info("subscriber.onComplete()") ); log.info("After Flux.subscribe()"); [main] - Before Flux.create()[main] - Before Flux.create() [main] - After Flux.create() [main] - Before Flux.create() [main] - After Flux.create() [main] - Before Flux.subscribe() Reactive Programming
  • 21. Subscribe log.info("Before Flux.create()"); Flux<Integer> flux = Flux.create(emitter -> { log.info("emitter.next({})", 1); emitter.next(1); log.info("emitter.complete()"); emitter.complete(); }); log.info("After Flux.create()"); log.info("Before Flux.subscribe()"); flux.subscribe( next -> log.info("subscriber.onNext({})", next), error -> log.info("subscriber.onError({})", error), () -> log.info("subscriber.onComplete()") ); log.info("After Flux.subscribe()"); [main] - Before Flux.create()[main] - Before Flux.create() [main] - After Flux.create() [main] - Before Flux.create() [main] - After Flux.create() [main] - Before Flux.subscribe() [main] - Before Flux.create() [main] - After Flux.create() [main] - Before Flux.subscribe() [main] - emitter.next(1) Reactive Programming
  • 22. Subscribe log.info("Before Flux.create()"); Flux<Integer> flux = Flux.create(emitter -> { log.info("emitter.next({})", 1); emitter.next(1); log.info("emitter.complete()"); emitter.complete(); }); log.info("After Flux.create()"); log.info("Before Flux.subscribe()"); flux.subscribe( next -> log.info("subscriber.onNext({})", next), error -> log.info("subscriber.onError({})", error), () -> log.info("subscriber.onComplete()") ); log.info("After Flux.subscribe()"); [main] - Before Flux.create()[main] - Before Flux.create() [main] - After Flux.create() [main] - Before Flux.create() [main] - After Flux.create() [main] - Before Flux.subscribe() [main] - Before Flux.create() [main] - After Flux.create() [main] - Before Flux.subscribe() [main] - emitter.next(1) [main] - Before Flux.create() [main] - After Flux.create() [main] - Before Flux.subscribe() [main] - emitter.next(1) [main] - subscriber.onNext(1) Reactive Programming
  • 23. Subscribe log.info("Before Flux.create()"); Flux<Integer> flux = Flux.create(emitter -> { log.info("emitter.next({})", 1); emitter.next(1); log.info("emitter.complete()"); emitter.complete(); }); log.info("After Flux.create()"); log.info("Before Flux.subscribe()"); flux.subscribe( next -> log.info("subscriber.onNext({})", next), error -> log.info("subscriber.onError({})", error), () -> log.info("subscriber.onComplete()") ); log.info("After Flux.subscribe()"); [main] - Before Flux.create()[main] - Before Flux.create() [main] - After Flux.create() [main] - Before Flux.create() [main] - After Flux.create() [main] - Before Flux.subscribe() [main] - Before Flux.create() [main] - After Flux.create() [main] - Before Flux.subscribe() [main] - emitter.next(1) [main] - Before Flux.create() [main] - After Flux.create() [main] - Before Flux.subscribe() [main] - emitter.next(1) [main] - subscriber.onNext(1) [main] - Before Flux.create() [main] - After Flux.create() [main] - Before Flux.subscribe() [main] - emitter.next(1) [main] - subscriber.onNext(1) [main] - emitter.complete() Reactive Programming
  • 24. Subscribe log.info("Before Flux.create()"); Flux<Integer> flux = Flux.create(emitter -> { log.info("emitter.next({})", 1); emitter.next(1); log.info("emitter.complete()"); emitter.complete(); }); log.info("After Flux.create()"); log.info("Before Flux.subscribe()"); flux.subscribe( next -> log.info("subscriber.onNext({})", next), error -> log.info("subscriber.onError({})", error), () -> log.info("subscriber.onComplete()") ); log.info("After Flux.subscribe()"); [main] - Before Flux.create()[main] - Before Flux.create() [main] - After Flux.create() [main] - Before Flux.create() [main] - After Flux.create() [main] - Before Flux.subscribe() [main] - Before Flux.create() [main] - After Flux.create() [main] - Before Flux.subscribe() [main] - emitter.next(1) [main] - Before Flux.create() [main] - After Flux.create() [main] - Before Flux.subscribe() [main] - emitter.next(1) [main] - subscriber.onNext(1) [main] - Before Flux.create() [main] - After Flux.create() [main] - Before Flux.subscribe() [main] - emitter.next(1) [main] - subscriber.onNext(1) [main] - emitter.complete() [main] - Before Flux.create() [main] - After Flux.create() [main] - Before Flux.subscribe() [main] - emitter.next(1) [main] - subscriber.onNext(1) [main] - emitter.complete() [main] - subscriber.onComplete() Reactive Programming
  • 25. Subscribe log.info("Before Flux.create()"); Flux<Integer> flux = Flux.create(emitter -> { log.info("emitter.next({})", 1); emitter.next(1); log.info("emitter.complete()"); emitter.complete(); }); log.info("After Flux.create()"); log.info("Before Flux.subscribe()"); flux.subscribe( next -> log.info("subscriber.onNext({})", next), error -> log.info("subscriber.onError({})", error), () -> log.info("subscriber.onComplete()") ); log.info("After Flux.subscribe()"); [main] - Before Flux.create()[main] - Before Flux.create() [main] - After Flux.create() [main] - Before Flux.create() [main] - After Flux.create() [main] - Before Flux.subscribe() [main] - Before Flux.create() [main] - After Flux.create() [main] - Before Flux.subscribe() [main] - emitter.next(1) [main] - Before Flux.create() [main] - After Flux.create() [main] - Before Flux.subscribe() [main] - emitter.next(1) [main] - subscriber.onNext(1) [main] - Before Flux.create() [main] - After Flux.create() [main] - Before Flux.subscribe() [main] - emitter.next(1) [main] - subscriber.onNext(1) [main] - emitter.complete() [main] - Before Flux.create() [main] - After Flux.create() [main] - Before Flux.subscribe() [main] - emitter.next(1) [main] - subscriber.onNext(1) [main] - emitter.complete() [main] - subscriber.onComplete() [main] - Before Flux.create() [main] - After Flux.create() [main] - Before Flux.subscribe() [main] - emitter.next(1) [main] - subscriber.onNext(1) [main] - emitter.complete() [main] - subscriber.onComplete() [main] - After Flux.subscribe() Reactive Programming
  • 26. Factory methods: fromIterable https://raw.githubusercontent.com/reactor/reactor-core/v3.0.6.RELEASE/src/docs/marble/fromiterable.png Reactive Programming Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions
  • 27. Factory methods: fromIterable public <T> Flux<T> fromIterable(Iterable<T> iterable) { return Flux.create(emitter -> { Iterator<T> iterator = iterable.iterator(); while (iterator.hasNext()) { emitter.next(iterator.next()); } emitter.complete(); }); } Reactive Programming Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions
  • 28. Factory methods: fromIterable public <T> Flux<T> fromIterable(Iterable<T> iterable) { return Flux.create(emitter -> { Iterator<T> iterator = iterable.iterator(); while (iterator.hasNext()) { emitter.next(iterator.next()); } emitter.complete(); }); } naive implementation Reactive Programming Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions
  • 29. Factory methods: fromCallable https://raw.githubusercontent.com/reactor/reactor-core/v3.0.6.RELEASE/src/docs/marble/fromcallable.png Mono<User> maybeUser = Mono .fromCallable(() -> loadUser(cwid)) Reactive Programming Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions
  • 30. StepVerifier Flux<String> flux = Flux.fromIterable(cwids).take(5); Reactive Programming Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions
  • 31. StepVerifier Flux<String> flux = Flux.fromIterable(cwids).take(5); Reactive Programming Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions StepVerifier.create(flux)
  • 32. StepVerifier Flux<String> flux = Flux.fromIterable(cwids).take(5); Reactive Programming Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions StepVerifier.create(flux) .expectSubscription()
  • 33. StepVerifier Flux<String> flux = Flux.fromIterable(cwids).take(5); Reactive Programming Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions StepVerifier.create(flux) .expectNext(cwids.get(0)) .expectSubscription()
  • 34. StepVerifier Flux<String> flux = Flux.fromIterable(cwids).take(5); Reactive Programming Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions StepVerifier.create(flux) .expectNext(cwids.get(0)) .expectNext(cwids.get(1)) .expectSubscription()
  • 35. StepVerifier Flux<String> flux = Flux.fromIterable(cwids).take(5); Reactive Programming Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions StepVerifier.create(flux) .expectNext(cwids.get(0)) .expectNext(cwids.get(1)) .expectNext(cwids.get(2), cwids.get(3), cwids.get(4)) .expectSubscription()
  • 36. StepVerifier Flux<String> flux = Flux.fromIterable(cwids).take(5); Reactive Programming Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions StepVerifier.create(flux) .expectNext(cwids.get(0)) .expectNext(cwids.get(1)) .expectNext(cwids.get(2), cwids.get(3), cwids.get(4)) .expectComplete() .expectSubscription()
  • 37. StepVerifier Flux<String> flux = Flux.fromIterable(cwids).take(5); Reactive Programming Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions StepVerifier.create(flux) .expectNext(cwids.get(0)) .expectNext(cwids.get(1)) .expectNext(cwids.get(2), cwids.get(3), cwids.get(4)) .expectComplete() .verify(); .expectSubscription()
  • 38. Operators: take Reactive Programming Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions https://raw.githubusercontent.com/reactor/reactor-core/master/src/docs/marble/take.png Flux.fromIterable(cwids) .take(3) ...
  • 39. Operators: map Reactive Programming Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions https://raw.githubusercontent.com/reactor/reactor-core/master/src/docs/marble/map.png Flux.fromIterable(cwids) .map(cwid -> loadUser(cwid)) ...
  • 40. Operators: flatMap Reactive Programming Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions https://raw.githubusercontent.com/reactor/reactor-core/master/src/docs/marble/flatmap.png Flux.fromIterable(cwids) .flatMap(cwid -> loadUserAsMono(cwid)) ...
  • 41. Operators: flatMap Reactive Programming Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions Flux<User> users = Flux .fromIterable(cwids) .flatMap(cwid -> loadUserAsMono(cwid));
  • 42. Operators: flatMap Reactive Programming Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions Flux<User> users = Flux .fromIterable(cwids) .flatMap(cwid -> loadUserAsMono(cwid)); private Mono<User> loadUserAsMono(String cwid) { return Mono.fromCallable(() -> loadUser(cwid)); }
  • 43. Operators: flatMap Reactive Programming Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions Flux<User> users = Flux .fromIterable(cwids) .flatMap(cwid -> loadUserAsMono(cwid)); private Mono<User> loadUserAsMono(String cwid) { return Mono.fromCallable(() -> loadUser(cwid)); } StepVerifier.create(users)
  • 44. Operators: flatMap Reactive Programming Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions Flux<User> users = Flux .fromIterable(cwids) .flatMap(cwid -> loadUserAsMono(cwid)); private Mono<User> loadUserAsMono(String cwid) { return Mono.fromCallable(() -> loadUser(cwid)); } StepVerifier.create(users) .expectNextMatches(hasCwid(cwids.get(0)))
  • 45. Operators: flatMap Reactive Programming Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions Flux<User> users = Flux .fromIterable(cwids) .flatMap(cwid -> loadUserAsMono(cwid)); private Mono<User> loadUserAsMono(String cwid) { return Mono.fromCallable(() -> loadUser(cwid)); } StepVerifier.create(users) .expectNextMatches(hasCwid(cwids.get(0))) .expectNextMatches(hasCwid(cwids.get(1)))
  • 46. Operators: flatMap Reactive Programming Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions Flux<User> users = Flux .fromIterable(cwids) .flatMap(cwid -> loadUserAsMono(cwid)); private Mono<User> loadUserAsMono(String cwid) { return Mono.fromCallable(() -> loadUser(cwid)); } StepVerifier.create(users) .expectNextMatches(hasCwid(cwids.get(0))) .expectNextMatches(hasCwid(cwids.get(1))) .expectNextMatches(hasCwid(cwids.get(2)))
  • 47. Operators: flatMap Reactive Programming Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions Flux<User> users = Flux .fromIterable(cwids) .flatMap(cwid -> loadUserAsMono(cwid)); private Mono<User> loadUserAsMono(String cwid) { return Mono.fromCallable(() -> loadUser(cwid)); } StepVerifier.create(users) .expectNextMatches(hasCwid(cwids.get(0))) .expectNextMatches(hasCwid(cwids.get(1))) .expectNextMatches(hasCwid(cwids.get(2))) ... .verifyComplete();
  • 48. Operators: flatMap Reactive Programming Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions Flux<User> users = Flux .fromIterable(cwids) .flatMap(cwid -> loadUserAsMono(cwid)); ? private Mono<User> loadUserAsMono(String cwid) { return Mono.fromCallable(() -> loadUser(cwid)); } StepVerifier.create(users) .expectNextMatches(hasCwid(cwids.get(0))) .expectNextMatches(hasCwid(cwids.get(1))) .expectNextMatches(hasCwid(cwids.get(2))) ... .verifyComplete();
  • 49. SubscribeOn log.info("Before Flux.create()"); Flux<Integer> flux = Flux.create(emitter -> { log.info("emitter.next({})", 1); emitter.next(1); log.info("emitter.complete()"); emitter.complete(); }) ; log.info("After Flux.create()"); log.info("Before Flux.subscribe()"); flux.subscribe( next -> log.info("subscriber.onNext({})", next), error -> log.info("subscriber.onError({})", error), () -> log.info("subscriber.onComplete()") ); log.info("After Flux.subscribe()"); Declarative Concurrency
  • 50. SubscribeOn log.info("Before Flux.create()"); Flux<Integer> flux = Flux.create(emitter -> { log.info("emitter.next({})", 1); emitter.next(1); log.info("emitter.complete()"); emitter.complete(); }) ; log.info("After Flux.create()"); log.info("Before Flux.subscribe()"); flux.subscribe( next -> log.info("subscriber.onNext({})", next), error -> log.info("subscriber.onError({})", error), () -> log.info("subscriber.onComplete()") ); log.info("After Flux.subscribe()"); Declarative Concurrency .subscribeOn(Schedulers.parallel())
  • 51. SubscribeOn log.info("Before Flux.create()"); Flux<Integer> flux = Flux.create(emitter -> { log.info("emitter.next({})", 1); emitter.next(1); log.info("emitter.complete()"); emitter.complete(); }) ; log.info("After Flux.create()"); log.info("Before Flux.subscribe()"); flux.subscribe( next -> log.info("subscriber.onNext({})", next), error -> log.info("subscriber.onError({})", error), () -> log.info("subscriber.onComplete()") ); log.info("After Flux.subscribe()"); [main] - Before Flux.create() Declarative Concurrency .subscribeOn(Schedulers.parallel())
  • 52. SubscribeOn log.info("Before Flux.create()"); Flux<Integer> flux = Flux.create(emitter -> { log.info("emitter.next({})", 1); emitter.next(1); log.info("emitter.complete()"); emitter.complete(); }) ; log.info("After Flux.create()"); log.info("Before Flux.subscribe()"); flux.subscribe( next -> log.info("subscriber.onNext({})", next), error -> log.info("subscriber.onError({})", error), () -> log.info("subscriber.onComplete()") ); log.info("After Flux.subscribe()"); [main] - Before Flux.create() Declarative Concurrency [main] - After Flux.create() .subscribeOn(Schedulers.parallel())
  • 53. SubscribeOn log.info("Before Flux.create()"); Flux<Integer> flux = Flux.create(emitter -> { log.info("emitter.next({})", 1); emitter.next(1); log.info("emitter.complete()"); emitter.complete(); }) ; log.info("After Flux.create()"); log.info("Before Flux.subscribe()"); flux.subscribe( next -> log.info("subscriber.onNext({})", next), error -> log.info("subscriber.onError({})", error), () -> log.info("subscriber.onComplete()") ); log.info("After Flux.subscribe()"); [main] - Before Flux.create() Declarative Concurrency [main] - After Flux.create() [main] - Before Flux.subscribe() .subscribeOn(Schedulers.parallel())
  • 54. SubscribeOn log.info("Before Flux.create()"); Flux<Integer> flux = Flux.create(emitter -> { log.info("emitter.next({})", 1); emitter.next(1); log.info("emitter.complete()"); emitter.complete(); }) ; log.info("After Flux.create()"); log.info("Before Flux.subscribe()"); flux.subscribe( next -> log.info("subscriber.onNext({})", next), error -> log.info("subscriber.onError({})", error), () -> log.info("subscriber.onComplete()") ); log.info("After Flux.subscribe()"); [main] - Before Flux.create() Declarative Concurrency [main] - After Flux.create() [main] - Before Flux.subscribe() [main] - After Flux.subscribe() .subscribeOn(Schedulers.parallel())
  • 55. SubscribeOn log.info("Before Flux.create()"); Flux<Integer> flux = Flux.create(emitter -> { log.info("emitter.next({})", 1); emitter.next(1); log.info("emitter.complete()"); emitter.complete(); }) ; log.info("After Flux.create()"); log.info("Before Flux.subscribe()"); flux.subscribe( next -> log.info("subscriber.onNext({})", next), error -> log.info("subscriber.onError({})", error), () -> log.info("subscriber.onComplete()") ); log.info("After Flux.subscribe()"); [main] - Before Flux.create() Declarative Concurrency [main] - After Flux.create() [main] - Before Flux.subscribe() [main] - After Flux.subscribe() [par1] - emitter.next(1).subscribeOn(Schedulers.parallel())
  • 56. SubscribeOn log.info("Before Flux.create()"); Flux<Integer> flux = Flux.create(emitter -> { log.info("emitter.next({})", 1); emitter.next(1); log.info("emitter.complete()"); emitter.complete(); }) ; log.info("After Flux.create()"); log.info("Before Flux.subscribe()"); flux.subscribe( next -> log.info("subscriber.onNext({})", next), error -> log.info("subscriber.onError({})", error), () -> log.info("subscriber.onComplete()") ); log.info("After Flux.subscribe()"); [main] - Before Flux.create() Declarative Concurrency [main] - After Flux.create() [main] - Before Flux.subscribe() [main] - After Flux.subscribe() [par1] - emitter.next(1) [par1] - subscriber.onNext(1) .subscribeOn(Schedulers.parallel())
  • 57. SubscribeOn log.info("Before Flux.create()"); Flux<Integer> flux = Flux.create(emitter -> { log.info("emitter.next({})", 1); emitter.next(1); log.info("emitter.complete()"); emitter.complete(); }) ; log.info("After Flux.create()"); log.info("Before Flux.subscribe()"); flux.subscribe( next -> log.info("subscriber.onNext({})", next), error -> log.info("subscriber.onError({})", error), () -> log.info("subscriber.onComplete()") ); log.info("After Flux.subscribe()"); [main] - Before Flux.create() Declarative Concurrency [main] - After Flux.create() [main] - Before Flux.subscribe() [main] - After Flux.subscribe() [par1] - emitter.next(1) [par1] - subscriber.onNext(1) [par1] - emitter.complete() .subscribeOn(Schedulers.parallel())
  • 58. SubscribeOn log.info("Before Flux.create()"); Flux<Integer> flux = Flux.create(emitter -> { log.info("emitter.next({})", 1); emitter.next(1); log.info("emitter.complete()"); emitter.complete(); }) ; log.info("After Flux.create()"); log.info("Before Flux.subscribe()"); flux.subscribe( next -> log.info("subscriber.onNext({})", next), error -> log.info("subscriber.onError({})", error), () -> log.info("subscriber.onComplete()") ); log.info("After Flux.subscribe()"); [main] - Before Flux.create() [par1] – subscriber.onComplete() Declarative Concurrency [main] - After Flux.create() [main] - Before Flux.subscribe() [main] - After Flux.subscribe() [par1] - emitter.next(1) [par1] - subscriber.onNext(1) [par1] - emitter.complete() .subscribeOn(Schedulers.parallel())
  • 59. SubscribeOn Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions log.info("Before Flux.fromIterable()"); Flux<User> users = Flux .fromIterable(cwids) .flatMap(cwid -> Mono .fromCallable(() -> loadUser(cwid))) ; Declarative Concurrency
  • 60. SubscribeOn Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions log.info("Before Flux.fromIterable()"); Flux<User> users = Flux .fromIterable(cwids) .flatMap(cwid -> Mono .fromCallable(() -> loadUser(cwid))) ; Declarative Concurrency .subscribeOn(Schedulers.parallel())
  • 61. SubscribeOn Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions log.info("Before Flux.fromIterable()"); Flux<User> users = Flux .fromIterable(cwids) .flatMap(cwid -> Mono .fromCallable(() -> loadUser(cwid))) ; Declarative Concurrency .subscribeOn(Schedulers.parallel()) [main] - Before Flux.fromIterable()
  • 62. SubscribeOn Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions log.info("Before Flux.fromIterable()"); Flux<User> users = Flux .fromIterable(cwids) .flatMap(cwid -> Mono .fromCallable(() -> loadUser(cwid))) ; Declarative Concurrency [par1] - loadUser(7896c6eb) .subscribeOn(Schedulers.parallel()) [main] - Before Flux.fromIterable()
  • 63. SubscribeOn Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions log.info("Before Flux.fromIterable()"); Flux<User> users = Flux .fromIterable(cwids) .flatMap(cwid -> Mono .fromCallable(() -> loadUser(cwid))) ; Declarative Concurrency [par1] - loadUser(7896c6eb) [par1] - loadUser(75ad9445).subscribeOn(Schedulers.parallel()) [main] - Before Flux.fromIterable()
  • 64. SubscribeOn Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions log.info("Before Flux.fromIterable()"); Flux<User> users = Flux .fromIterable(cwids) .flatMap(cwid -> Mono .fromCallable(() -> loadUser(cwid))) ; Declarative Concurrency [par1] - loadUser(7896c6eb) [par1] - loadUser(75ad9445) [par1] - loadUser(e2d4c51d) .subscribeOn(Schedulers.parallel()) [main] - Before Flux.fromIterable()
  • 65. SubscribeOn Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions log.info("Before Flux.fromIterable()"); Flux<User> users = Flux .fromIterable(cwids) .flatMap(cwid -> Mono .fromCallable(() -> loadUser(cwid))) ; Declarative Concurrency [par1] - loadUser(7896c6eb) [par1] - loadUser(75ad9445) [par1] - loadUser(e2d4c51d) .subscribeOn(Schedulers.parallel()) StepVerifier.create(users) [main] - Before Flux.fromIterable()
  • 66. SubscribeOn Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions log.info("Before Flux.fromIterable()"); Flux<User> users = Flux .fromIterable(cwids) .flatMap(cwid -> Mono .fromCallable(() -> loadUser(cwid))) ; Declarative Concurrency [par1] - loadUser(7896c6eb) [par1] - loadUser(75ad9445) [par1] - loadUser(e2d4c51d) .subscribeOn(Schedulers.parallel()) StepVerifier.create(users) .expectNextMatches(hasCwid(cwids.get(0))) [main] - Before Flux.fromIterable()
  • 67. SubscribeOn Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions log.info("Before Flux.fromIterable()"); Flux<User> users = Flux .fromIterable(cwids) .flatMap(cwid -> Mono .fromCallable(() -> loadUser(cwid))) ; Declarative Concurrency [par1] - loadUser(7896c6eb) [par1] - loadUser(75ad9445) [par1] - loadUser(e2d4c51d) .subscribeOn(Schedulers.parallel()) StepVerifier.create(users) .expectNextMatches(hasCwid(cwids.get(0))) .expectNextMatches(hasCwid(cwids.get(1))) [main] - Before Flux.fromIterable()
  • 68. SubscribeOn Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions log.info("Before Flux.fromIterable()"); Flux<User> users = Flux .fromIterable(cwids) .flatMap(cwid -> Mono .fromCallable(() -> loadUser(cwid))) ; Declarative Concurrency [par1] - loadUser(7896c6eb) [par1] - loadUser(75ad9445) [par1] - loadUser(e2d4c51d) .subscribeOn(Schedulers.parallel()) StepVerifier.create(users) .expectNextMatches(hasCwid(cwids.get(0))) .expectNextMatches(hasCwid(cwids.get(1))) .expectNextMatches(hasCwid(cwids.get(2))) [main] - Before Flux.fromIterable()
  • 69. SubscribeOn Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions log.info("Before Flux.fromIterable()"); Flux<User> users = Flux .fromIterable(cwids) .flatMap(cwid -> Mono .fromCallable(() -> loadUser(cwid))) ; Declarative Concurrency [par1] - loadUser(7896c6eb) [par1] - loadUser(75ad9445) [par1] - loadUser(e2d4c51d) .subscribeOn(Schedulers.parallel()) StepVerifier.create(users) .expectNextMatches(hasCwid(cwids.get(0))) .expectNextMatches(hasCwid(cwids.get(1))) .expectNextMatches(hasCwid(cwids.get(2))) ... .verifyComplete(); [main] - Before Flux.fromIterable()
  • 70. SubscribeOn Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions log.info("Before Flux.fromIterable()"); Flux<User> users = Flux .fromIterable(cwids) .flatMap(cwid -> Mono .fromCallable(() -> loadUser(cwid))) ; Declarative Concurrency [par1] - loadUser(7896c6eb) [par1] - loadUser(75ad9445) [par1] - loadUser(e2d4c51d) .subscribeOn(Schedulers.parallel()) StepVerifier.create(users) .expectNextMatches(hasCwid(cwids.get(0))) .expectNextMatches(hasCwid(cwids.get(1))) .expectNextMatches(hasCwid(cwids.get(2))) ... .verifyComplete(); ✓ [main] - Before Flux.fromIterable()
  • 71. SubscribeOn Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions log.info("Before Flux.fromIterable()"); Flux<User> users = Flux .fromIterable(cwids) .flatMap(cwid -> Mono .fromCallable(() -> loadUser(cwid))) ; Declarative Concurrency [par1] - loadUser(7896c6eb) [par1] - loadUser(75ad9445) [par1] - loadUser(e2d4c51d) .subscribeOn(Schedulers.parallel()) StepVerifier.create(users) .expectNextMatches(hasCwid(cwids.get(0))) .expectNextMatches(hasCwid(cwids.get(1))) .expectNextMatches(hasCwid(cwids.get(2))) ... .verifyComplete(); ✓ [main] - Before Flux.fromIterable() ✗
  • 72. SubscribeOn Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions log.info("Before Flux.fromIterable()"); Flux<User> users = Flux .fromIterable(cwids) .flatMap(cwid -> Mono .fromCallable(() -> loadUser(cwid)) ); Declarative Concurrency
  • 73. SubscribeOn Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions log.info("Before Flux.fromIterable()"); Flux<User> users = Flux .fromIterable(cwids) .flatMap(cwid -> Mono .fromCallable(() -> loadUser(cwid)) ); Declarative Concurrency .subscribeOn(Schedulers.parallel())
  • 74. SubscribeOn Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions log.info("Before Flux.fromIterable()"); Flux<User> users = Flux .fromIterable(cwids) .flatMap(cwid -> Mono .fromCallable(() -> loadUser(cwid)) ); Declarative Concurrency .subscribeOn(Schedulers.parallel()) [main] - Before Flux.fromIterable()
  • 75. SubscribeOn Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions log.info("Before Flux.fromIterable()"); Flux<User> users = Flux .fromIterable(cwids) .flatMap(cwid -> Mono .fromCallable(() -> loadUser(cwid)) ); Declarative Concurrency [par1] - loadUser(7896c6eb) .subscribeOn(Schedulers.parallel()) [main] - Before Flux.fromIterable()
  • 76. SubscribeOn Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions log.info("Before Flux.fromIterable()"); Flux<User> users = Flux .fromIterable(cwids) .flatMap(cwid -> Mono .fromCallable(() -> loadUser(cwid)) ); Declarative Concurrency [par1] - loadUser(7896c6eb) [par2] - loadUser(75ad9445).subscribeOn(Schedulers.parallel()) [main] - Before Flux.fromIterable()
  • 77. SubscribeOn Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions log.info("Before Flux.fromIterable()"); Flux<User> users = Flux .fromIterable(cwids) .flatMap(cwid -> Mono .fromCallable(() -> loadUser(cwid)) ); Declarative Concurrency [par1] - loadUser(7896c6eb) [par2] - loadUser(75ad9445) [par3] - loadUser(e2d4c51d) .subscribeOn(Schedulers.parallel()) [main] - Before Flux.fromIterable()
  • 78. SubscribeOn Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions log.info("Before Flux.fromIterable()"); Flux<User> users = Flux .fromIterable(cwids) .flatMap(cwid -> Mono .fromCallable(() -> loadUser(cwid)) ); Declarative Concurrency [par1] - loadUser(7896c6eb) [par2] - loadUser(75ad9445) [par3] - loadUser(e2d4c51d) .subscribeOn(Schedulers.parallel()) StepVerifier.create(users) .expectNextMatches(hasCwid(cwids.get(0))) .expectNextMatches(hasCwid(cwids.get(1))) .expectNextMatches(hasCwid(cwids.get(2))) ... .verifyComplete(); [main] - Before Flux.fromIterable()
  • 79. SubscribeOn Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions log.info("Before Flux.fromIterable()"); Flux<User> users = Flux .fromIterable(cwids) .flatMap(cwid -> Mono .fromCallable(() -> loadUser(cwid)) ); Declarative Concurrency [par1] - loadUser(7896c6eb) [par2] - loadUser(75ad9445) [par3] - loadUser(e2d4c51d) .subscribeOn(Schedulers.parallel()) StepVerifier.create(users) .expectNextMatches(hasCwid(cwids.get(0))) .expectNextMatches(hasCwid(cwids.get(1))) .expectNextMatches(hasCwid(cwids.get(2))) ... .verifyComplete(); ✗ [main] - Before Flux.fromIterable()
  • 80. SubscribeOn Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions log.info("Before Flux.fromIterable()"); Flux<User> users = Flux .fromIterable(cwids) .flatMap(cwid -> Mono .fromCallable(() -> loadUser(cwid)) ); Declarative Concurrency [par1] - loadUser(7896c6eb) [par2] - loadUser(75ad9445) [par3] - loadUser(e2d4c51d) .subscribeOn(Schedulers.parallel()) StepVerifier.create(users) .expectNextMatches(hasCwid(cwids.get(0))) .expectNextMatches(hasCwid(cwids.get(1))) .expectNextMatches(hasCwid(cwids.get(2))) ... .verifyComplete(); ✗ [main] - Before Flux.fromIterable() ✓
  • 81. Virtual Time Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions log.info("Before Flux.fromIterable()"); Flux<User> users = Flux .fromIterable(cwids) .flatMap(cwid -> Mono .fromCallable(() -> loadUser(cwid)) .subscribeOn(Schedulers.parallel())); StepVerifier Declarative Concurrency
  • 82. Virtual Time Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions log.info("Before Flux.fromIterable()"); Flux<User> users = Flux .fromIterable(cwids) .flatMap(cwid -> Mono .fromCallable(() -> loadUser(cwid)) .subscribeOn(Schedulers.parallel())); StepVerifier Declarative Concurrency .withVirtualTime(users)
  • 83. Virtual Time Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions log.info("Before Flux.fromIterable()"); Flux<User> users = Flux .fromIterable(cwids) .flatMap(cwid -> Mono .fromCallable(() -> loadUser(cwid)) .subscribeOn(Schedulers.parallel())); StepVerifier Declarative Concurrency .withVirtualTime(users) .thenAwait()
  • 84. Virtual Time Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions log.info("Before Flux.fromIterable()"); Flux<User> users = Flux .fromIterable(cwids) .flatMap(cwid -> Mono .fromCallable(() -> loadUser(cwid)) .subscribeOn(Schedulers.parallel())); StepVerifier Declarative Concurrency .withVirtualTime(users) .thenAwait() .expectNextMatches(hasCwid(cwids.get(0)))
  • 85. Virtual Time Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions log.info("Before Flux.fromIterable()"); Flux<User> users = Flux .fromIterable(cwids) .flatMap(cwid -> Mono .fromCallable(() -> loadUser(cwid)) .subscribeOn(Schedulers.parallel())); StepVerifier Declarative Concurrency .withVirtualTime(users) .thenAwait() .expectNextMatches(hasCwid(cwids.get(0))) .expectNextMatches(hasCwid(cwids.get(1)))
  • 86. Virtual Time Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions log.info("Before Flux.fromIterable()"); Flux<User> users = Flux .fromIterable(cwids) .flatMap(cwid -> Mono .fromCallable(() -> loadUser(cwid)) .subscribeOn(Schedulers.parallel())); StepVerifier Declarative Concurrency .withVirtualTime(users) .thenAwait() .expectNextMatches(hasCwid(cwids.get(0))) .expectNextMatches(hasCwid(cwids.get(1))) .expectNextMatches(hasCwid(cwids.get(2)))
  • 87. Virtual Time Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions log.info("Before Flux.fromIterable()"); Flux<User> users = Flux .fromIterable(cwids) .flatMap(cwid -> Mono .fromCallable(() -> loadUser(cwid)) .subscribeOn(Schedulers.parallel())); StepVerifier Declarative Concurrency .withVirtualTime(users) .thenAwait() .expectNextMatches(hasCwid(cwids.get(0))) .expectNextMatches(hasCwid(cwids.get(1))) .expectNextMatches(hasCwid(cwids.get(2))) ... .verifyComplete();
  • 88. Virtual Time Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions log.info("Before Flux.fromIterable()"); Flux<User> users = Flux .fromIterable(cwids) .flatMap(cwid -> Mono .fromCallable(() -> loadUser(cwid)) .subscribeOn(Schedulers.parallel())); StepVerifier Declarative Concurrency Supplier< > () -> .withVirtualTime(users) .thenAwait() .expectNextMatches(hasCwid(cwids.get(0))) .expectNextMatches(hasCwid(cwids.get(1))) .expectNextMatches(hasCwid(cwids.get(2))) ... .verifyComplete();
  • 89. Virtual Time Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions log.info("Before Flux.fromIterable()"); Flux<User> users = Flux .fromIterable(cwids) .flatMap(cwid -> Mono .fromCallable(() -> loadUser(cwid)) .subscribeOn(Schedulers.parallel())); StepVerifier Declarative Concurrency Supplier< > () -> .withVirtualTime(users) .thenAwait() .expectNextMatches(hasCwid(cwids.get(0))) .expectNextMatches(hasCwid(cwids.get(1))) .expectNextMatches(hasCwid(cwids.get(2))) ... .verifyComplete(); ✓
  • 90. Let‘s go wild ... Declarative Concurrency Flux .fromIterable(cwids) .flatMap(cwid -> Mono.fromCallable(() -> loadUser(cwid)) .subscribeOn(Schedulers.parallel()));
  • 91. Let‘s go wild ... Declarative Concurrency Flux .fromIterable(cwids) .flatMap(cwid -> Mono.fromCallable(() -> loadUser(cwid)) .subscribeOn(Schedulers.parallel())); CONCURRENCY
  • 92. Let‘s go wild ... Declarative Concurrency Flux .fromIterable(cwids) .flatMap(cwid -> Mono.fromCallable(() -> loadUser(cwid)) .subscribeOn(Schedulers.parallel())); .timeout(Duration.ofMillis(250), Schedulers.single()) TIMEOUT CONCURRENCY
  • 93. Let‘s go wild ... Declarative Concurrency Flux .fromIterable(cwids) .flatMap(cwid -> Mono.fromCallable(() -> loadUser(cwid)) .subscribeOn(Schedulers.parallel())); .timeout(Duration.ofMillis(250), Schedulers.single()) .retry(numRetries) TIMEOUT RETRY CONCURRENCY
  • 94. Let‘s go wild ... Declarative Concurrency Flux .fromIterable(cwids) .flatMap(cwid -> Mono.fromCallable(() -> loadUser(cwid)) .subscribeOn(Schedulers.parallel())); .timeout(Duration.ofMillis(250), Schedulers.single()) .retryWhen(errors -> errors.zipWith(Flux.range(0, MAX_VALUE), (err, idx) -> { if (idx < numRetries) { return Mono.just(err).delayElement(withExponentialBackoff(idx)); } else { return Mono.error(err); } }).flatMap(Function.identity())) TIMEOUT RETRY WITH EXPONENTIAL BACKOFF CONCURRENCY
  • 95. Let‘s go wild ... Declarative Concurrency Flux .fromIterable(cwids) .flatMap(cwid -> Mono.fromCallable(() -> loadUser(cwid)) .subscribeOn(Schedulers.parallel())); .timeout(Duration.ofMillis(250), Schedulers.single()) .retryWhen(errors -> errors.zipWith(Flux.range(0, MAX_VALUE), (err, idx) -> { if (idx < numRetries) { return Mono.just(err).delayElement(withExponentialBackoff(idx)); } else { return Mono.error(err); } }).flatMap(Function.identity())) long ms = (long) Math.pow(10, idx); return Duration.ofMillis(ms); TIMEOUT RETRY WITH EXPONENTIAL BACKOFF CONCURRENCY
  • 96. Let‘s go wild ... Declarative Concurrency Flux .fromIterable(cwids) .flatMap(cwid -> Mono.fromCallable(() -> loadUser(cwid)) .subscribeOn(Schedulers.parallel())); .timeout(Duration.ofMillis(250), Schedulers.single()) .retryWhen(errors -> errors.zipWith(Flux.range(0, MAX_VALUE), (err, idx) -> { if (idx < numRetries) { return Mono.just(err).delayElement(withExponentialBackoff(idx)); } else { return Mono.error(err); } }).flatMap(Function.identity())) TIMEOUT RETRY WITH EXPONENTIAL BACKOFF CONCURRENCY
  • 97. Let‘s go wild ... Declarative Concurrency Flux .fromIterable(cwids) .flatMap(cwid -> Mono.fromCallable(() -> loadUser(cwid)) .subscribeOn(Schedulers.parallel())); .timeout(Duration.ofMillis(250), Schedulers.single()) .retryWhen(errors -> errors.zipWith(Flux.range(0, MAX_VALUE), (err, idx) -> { if (idx < numRetries) { return Mono.just(err).delayElement(withExponentialBackoff(idx)); } else { return Mono.error(err); } }).flatMap(Function.identity())) .map(Either::<String, User>right) .otherwiseReturn(left(cwid)) Flux<Either<String, User>> users = TIMEOUT RETRY WITH EXPONENTIAL BACKOFF ERROR HANDLINGCONCURRENCY
  • 98. Backpressure Reactive Streams Akka Streams ReactorRxJava 2 Back- pressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions
  • 99. Reactive Streams § Flow API in Java 9: java.util.concurrent.Flow § Standard for asynchronous stream processing § Pivotal, Lightbend, Netflix, Oracle, Red Hat and others Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions Backpressure
  • 100. Reactive Streams public class Flow { interface Processor<T, R> { ... } interface Publisher<T> { ... } interface Subscriber<T> { ... } interface Subscription { ... } } Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions Backpressure
  • 101. Subscriber Pushing Backpressure Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions Publisher
  • 102. Subscriber Pushing Backpressure Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions Publisher
  • 103. Subscriber Pushing Backpressure Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions Publisher
  • 104. Subscriber Pushing Backpressure Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions Publisher
  • 105. Subscriber Pushing Backpressure Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions Publisher
  • 106. Subscriber Pushing Backpressure Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions Publisher
  • 107. Subscriber Pushing Backpressure Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions Publisher
  • 108. Subscriber Pushing Backpressure Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions Publisher
  • 109. Pushing Backpressure Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions ExecutorService executorService = new ThreadPoolExecutor( 10, 10, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(500) );
  • 110. Pushing Backpressure Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions List<Future<User>> eventualUsers = cwids.stream() .map(cwid -> executorService.submit(() -> loadUser(cwid))) .collect(toList()); List<User> users = eventualUsers.stream() .map(eventualUser -> { try { return eventualUser.get(); } catch (Exception e) { throw new RuntimeException(e); } }) .collect(toList());
  • 111. Pushing Backpressure Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@632ceb35 rejected from java.util.concurrent.ThreadPoolExecutor@1c93f6e1[ Running, pool size = 10, active threads = 10, queued tasks = 500, completed tasks = 0 ]
  • 112. Subscriber Pulling and Pushing Backpressure Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions Publisher Subscription
  • 113. Subscriber request(3) Pulling and Pushing Backpressure Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions Publisher Subscription
  • 114. Subscriber Pulling and Pushing Backpressure Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions Publisher Subscription
  • 115. Subscriber Pulling and Pushing Backpressure Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions Publisher Subscription
  • 116. Subscriber Pulling and Pushing Backpressure Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions Publisher Subscription
  • 117. Subscriber Pulling and Pushing Backpressure Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions Publisher Subscription
  • 118. Subscriber Pulling and Pushing Backpressure Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions Publisher Subscription
  • 119. Subscriber Pulling and Pushing Backpressure Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions Publisher Subscription
  • 120. Subscriber Pulling and Pushing Backpressure Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions Publisher Subscription
  • 121. Subscriber Pulling and Pushing Backpressure Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions Publisher Subscription request(2)
  • 122. Subscriber Pulling and Pushing Backpressure Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions Publisher Subscription
  • 123. Subscriber Pulling and Pushing Backpressure Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions Publisher Subscription
  • 124. Subscriber Pulling and Pushing Backpressure Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions Publisher Subscription
  • 125. Subscriber Pulling and Pushing Backpressure Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions Publisher Subscription
  • 126. Subscriber Pulling and Pushing Backpressure Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions Publisher Subscription
  • 127. List<User> users = Flux.fromIterable(cwids) .flatMap(cwid -> Mono .fromCallable(() -> loadUser(cwid)) .subscribeOn(Schedulers.fromExecutor(executorService))) .collectList() .block(); Pulling and Pushing Backpressure Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions
  • 128. class FluxIterable<T> { Iterable<? extends T> iterable; FluxIterable(Iterable<? extends T> iterable) { this.iterable = iterable; } // more than 500 lines of code } Pulling and Pushing: fromIterable Backpressure Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions naive implementation of fromIterable does not enable backpressure !
  • 129. Pulling and Pushing: flatMap Backpressure Reactive Streams Akka Streams ReactorRxJava 2 Backpressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions https://raw.githubusercontent.com/reactor/reactor-core/v3.0.6.RELEASE/src/docs/marble/flatmapc.png
  • 130. Conclusion Reactive Streams Akka Streams ReactorRxJava 2 Back- pressure Marble Diagrams Function Composition with Higher Order Functions Functional Programming Declarative Programming REACTIVE PROGRAMMING REACTIVE SYSTEMS Reactive Extensions
  • 131. What‘s more? § Concurrency with publishOn and ParallelFlux § Declarative Error Handling § Logging and Monitoring § Cold Streams vs. Hot Streams § C10K and Non-blocking IO § Reactive Streams in the Web Conclusion