SlideShare a Scribd company logo
1 of 132
Download to read offline
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

What's hot

Php internal architecture
Php internal architecturePhp internal architecture
Php internal architectureElizabeth Smith
 
REST APIs with Spring
REST APIs with SpringREST APIs with Spring
REST APIs with SpringJoshua Long
 
Understanding Reactive Programming
Understanding Reactive ProgrammingUnderstanding Reactive Programming
Understanding Reactive ProgrammingAndres Almiray
 
Spring boot introduction
Spring boot introductionSpring boot introduction
Spring boot introductionRasheed Waraich
 
Reactive Programming In Java Using: Project Reactor
Reactive Programming In Java Using: Project ReactorReactive Programming In Java Using: Project Reactor
Reactive Programming In Java Using: Project ReactorKnoldus Inc.
 
Monitoring Flink with Prometheus
Monitoring Flink with PrometheusMonitoring Flink with Prometheus
Monitoring Flink with PrometheusMaximilian Bode
 
How to Avoid Common Mistakes When Using Reactor Netty
How to Avoid Common Mistakes When Using Reactor NettyHow to Avoid Common Mistakes When Using Reactor Netty
How to Avoid Common Mistakes When Using Reactor NettyVMware Tanzu
 
Best Practices for Middleware and Integration Architecture Modernization with...
Best Practices for Middleware and Integration Architecture Modernization with...Best Practices for Middleware and Integration Architecture Modernization with...
Best Practices for Middleware and Integration Architecture Modernization with...Claus Ibsen
 
Kafka’s New Control Plane: The Quorum Controller | Colin McCabe, Confluent
Kafka’s New Control Plane: The Quorum Controller | Colin McCabe, ConfluentKafka’s New Control Plane: The Quorum Controller | Colin McCabe, Confluent
Kafka’s New Control Plane: The Quorum Controller | Colin McCabe, ConfluentHostedbyConfluent
 
Spring - Part 1 - IoC, Di and Beans
Spring - Part 1 - IoC, Di and Beans Spring - Part 1 - IoC, Di and Beans
Spring - Part 1 - IoC, Di and Beans Hitesh-Java
 
Towards Functional Programming through Hexagonal Architecture
Towards Functional Programming through Hexagonal ArchitectureTowards Functional Programming through Hexagonal Architecture
Towards Functional Programming through Hexagonal ArchitectureCodelyTV
 
Dynamically Scaling Data Streams across Multiple Kafka Clusters with Zero Fli...
Dynamically Scaling Data Streams across Multiple Kafka Clusters with Zero Fli...Dynamically Scaling Data Streams across Multiple Kafka Clusters with Zero Fli...
Dynamically Scaling Data Streams across Multiple Kafka Clusters with Zero Fli...Flink Forward
 
Reactive Programming
Reactive ProgrammingReactive Programming
Reactive ProgrammingKnoldus Inc.
 
Zero-Copy Event-Driven Servers with Netty
Zero-Copy Event-Driven Servers with NettyZero-Copy Event-Driven Servers with Netty
Zero-Copy Event-Driven Servers with NettyDaniel Bimschas
 

What's hot (20)

Php internal architecture
Php internal architecturePhp internal architecture
Php internal architecture
 
Project Reactor By Example
Project Reactor By ExampleProject Reactor By Example
Project Reactor By Example
 
REST APIs with Spring
REST APIs with SpringREST APIs with Spring
REST APIs with Spring
 
Understanding Reactive Programming
Understanding Reactive ProgrammingUnderstanding Reactive Programming
Understanding Reactive Programming
 
Spring boot introduction
Spring boot introductionSpring boot introduction
Spring boot introduction
 
Reactive Programming In Java Using: Project Reactor
Reactive Programming In Java Using: Project ReactorReactive Programming In Java Using: Project Reactor
Reactive Programming In Java Using: Project Reactor
 
Monitoring Flink with Prometheus
Monitoring Flink with PrometheusMonitoring Flink with Prometheus
Monitoring Flink with Prometheus
 
Quarkus k8s
Quarkus   k8sQuarkus   k8s
Quarkus k8s
 
Testing Spring Applications
Testing Spring ApplicationsTesting Spring Applications
Testing Spring Applications
 
How to Avoid Common Mistakes When Using Reactor Netty
How to Avoid Common Mistakes When Using Reactor NettyHow to Avoid Common Mistakes When Using Reactor Netty
How to Avoid Common Mistakes When Using Reactor Netty
 
Best Practices for Middleware and Integration Architecture Modernization with...
Best Practices for Middleware and Integration Architecture Modernization with...Best Practices for Middleware and Integration Architecture Modernization with...
Best Practices for Middleware and Integration Architecture Modernization with...
 
Kafka’s New Control Plane: The Quorum Controller | Colin McCabe, Confluent
Kafka’s New Control Plane: The Quorum Controller | Colin McCabe, ConfluentKafka’s New Control Plane: The Quorum Controller | Colin McCabe, Confluent
Kafka’s New Control Plane: The Quorum Controller | Colin McCabe, Confluent
 
Java Spring Framework
Java Spring FrameworkJava Spring Framework
Java Spring Framework
 
Spring - Part 1 - IoC, Di and Beans
Spring - Part 1 - IoC, Di and Beans Spring - Part 1 - IoC, Di and Beans
Spring - Part 1 - IoC, Di and Beans
 
Towards Functional Programming through Hexagonal Architecture
Towards Functional Programming through Hexagonal ArchitectureTowards Functional Programming through Hexagonal Architecture
Towards Functional Programming through Hexagonal Architecture
 
What's new in Java 11
What's new in Java 11What's new in Java 11
What's new in Java 11
 
Dynamically Scaling Data Streams across Multiple Kafka Clusters with Zero Fli...
Dynamically Scaling Data Streams across Multiple Kafka Clusters with Zero Fli...Dynamically Scaling Data Streams across Multiple Kafka Clusters with Zero Fli...
Dynamically Scaling Data Streams across Multiple Kafka Clusters with Zero Fli...
 
Reactive Programming
Reactive ProgrammingReactive Programming
Reactive Programming
 
Zero-Copy Event-Driven Servers with Netty
Zero-Copy Event-Driven Servers with NettyZero-Copy Event-Driven Servers with Netty
Zero-Copy Event-Driven Servers with Netty
 
Spring Webflux
Spring WebfluxSpring Webflux
Spring Webflux
 

Similar to Declarative Concurrency with Reactive Programming

Going Reactive with Relational Databases
Going Reactive with Relational DatabasesGoing Reactive with Relational Databases
Going Reactive with Relational DatabasesIvaylo Pashov
 
GDG DevFest 2015 - Reactive approach for slowpokes
GDG DevFest 2015 - Reactive approach for slowpokesGDG DevFest 2015 - Reactive approach for slowpokes
GDG DevFest 2015 - Reactive approach for slowpokesSergey Tarasevich
 
Akka.NET streams and reactive streams
Akka.NET streams and reactive streamsAkka.NET streams and reactive streams
Akka.NET streams and reactive streamsBartosz Sypytkowski
 
Reactive Fault Tolerant Programming with Hystrix and RxJava
Reactive Fault Tolerant Programming with Hystrix and RxJavaReactive Fault Tolerant Programming with Hystrix and RxJava
Reactive Fault Tolerant Programming with Hystrix and RxJavaMatt Stine
 
Reactive java programming for the impatient
Reactive java programming for the impatientReactive java programming for the impatient
Reactive java programming for the impatientGrant Steinfeld
 
Reactive programming for java developers
Reactive programming for java developersReactive programming for java developers
Reactive programming for java developersConstantin Popa
 
Practical RxJava for Android
Practical RxJava for AndroidPractical RxJava for Android
Practical RxJava for AndroidTomáš Kypta
 
Understanding reactive programming with microsoft reactive extensions
Understanding reactive programming  with microsoft reactive extensionsUnderstanding reactive programming  with microsoft reactive extensions
Understanding reactive programming with microsoft reactive extensionsOleksandr Zhevzhyk
 
Programming Sideways: Asynchronous Techniques for Android
Programming Sideways: Asynchronous Techniques for AndroidProgramming Sideways: Asynchronous Techniques for Android
Programming Sideways: Asynchronous Techniques for AndroidEmanuele Di Saverio
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on AndroidTomáš Kypta
 
Asynchronous stream processing with Akka Streams
Asynchronous stream processing with Akka StreamsAsynchronous stream processing with Akka Streams
Asynchronous stream processing with Akka StreamsJohan Andrén
 
Productionalizing spark streaming applications
Productionalizing spark streaming applicationsProductionalizing spark streaming applications
Productionalizing spark streaming applicationsRobert Sanders
 
Journey into Reactive Streams and Akka Streams
Journey into Reactive Streams and Akka StreamsJourney into Reactive Streams and Akka Streams
Journey into Reactive Streams and Akka StreamsKevin Webber
 
Intro to Reactive Thinking and RxJava 2
Intro to Reactive Thinking and RxJava 2Intro to Reactive Thinking and RxJava 2
Intro to Reactive Thinking and RxJava 2JollyRogers5
 
How to Think in RxJava Before Reacting
How to Think in RxJava Before ReactingHow to Think in RxJava Before Reacting
How to Think in RxJava Before ReactingIndicThreads
 
4Developers 2015: Programowanie synchroniczne i asynchroniczne - dwa światy k...
4Developers 2015: Programowanie synchroniczne i asynchroniczne - dwa światy k...4Developers 2015: Programowanie synchroniczne i asynchroniczne - dwa światy k...
4Developers 2015: Programowanie synchroniczne i asynchroniczne - dwa światy k...PROIDEA
 
점진적인 레거시 웹 애플리케이션 개선 과정
점진적인 레거시 웹 애플리케이션 개선 과정점진적인 레거시 웹 애플리케이션 개선 과정
점진적인 레거시 웹 애플리케이션 개선 과정Arawn Park
 
Building Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJavaBuilding Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJavaRick Warren
 
Next generation message driven systems with Akka
Next generation message driven systems with AkkaNext generation message driven systems with Akka
Next generation message driven systems with AkkaJohan Andrén
 
Building Stateful Microservices With Akka
Building Stateful Microservices With AkkaBuilding Stateful Microservices With Akka
Building Stateful Microservices With AkkaYaroslav Tkachenko
 

Similar to Declarative Concurrency with Reactive Programming (20)

Going Reactive with Relational Databases
Going Reactive with Relational DatabasesGoing Reactive with Relational Databases
Going Reactive with Relational Databases
 
GDG DevFest 2015 - Reactive approach for slowpokes
GDG DevFest 2015 - Reactive approach for slowpokesGDG DevFest 2015 - Reactive approach for slowpokes
GDG DevFest 2015 - Reactive approach for slowpokes
 
Akka.NET streams and reactive streams
Akka.NET streams and reactive streamsAkka.NET streams and reactive streams
Akka.NET streams and reactive streams
 
Reactive Fault Tolerant Programming with Hystrix and RxJava
Reactive Fault Tolerant Programming with Hystrix and RxJavaReactive Fault Tolerant Programming with Hystrix and RxJava
Reactive Fault Tolerant Programming with Hystrix and RxJava
 
Reactive java programming for the impatient
Reactive java programming for the impatientReactive java programming for the impatient
Reactive java programming for the impatient
 
Reactive programming for java developers
Reactive programming for java developersReactive programming for java developers
Reactive programming for java developers
 
Practical RxJava for Android
Practical RxJava for AndroidPractical RxJava for Android
Practical RxJava for Android
 
Understanding reactive programming with microsoft reactive extensions
Understanding reactive programming  with microsoft reactive extensionsUnderstanding reactive programming  with microsoft reactive extensions
Understanding reactive programming with microsoft reactive extensions
 
Programming Sideways: Asynchronous Techniques for Android
Programming Sideways: Asynchronous Techniques for AndroidProgramming Sideways: Asynchronous Techniques for Android
Programming Sideways: Asynchronous Techniques for Android
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on Android
 
Asynchronous stream processing with Akka Streams
Asynchronous stream processing with Akka StreamsAsynchronous stream processing with Akka Streams
Asynchronous stream processing with Akka Streams
 
Productionalizing spark streaming applications
Productionalizing spark streaming applicationsProductionalizing spark streaming applications
Productionalizing spark streaming applications
 
Journey into Reactive Streams and Akka Streams
Journey into Reactive Streams and Akka StreamsJourney into Reactive Streams and Akka Streams
Journey into Reactive Streams and Akka Streams
 
Intro to Reactive Thinking and RxJava 2
Intro to Reactive Thinking and RxJava 2Intro to Reactive Thinking and RxJava 2
Intro to Reactive Thinking and RxJava 2
 
How to Think in RxJava Before Reacting
How to Think in RxJava Before ReactingHow to Think in RxJava Before Reacting
How to Think in RxJava Before Reacting
 
4Developers 2015: Programowanie synchroniczne i asynchroniczne - dwa światy k...
4Developers 2015: Programowanie synchroniczne i asynchroniczne - dwa światy k...4Developers 2015: Programowanie synchroniczne i asynchroniczne - dwa światy k...
4Developers 2015: Programowanie synchroniczne i asynchroniczne - dwa światy k...
 
점진적인 레거시 웹 애플리케이션 개선 과정
점진적인 레거시 웹 애플리케이션 개선 과정점진적인 레거시 웹 애플리케이션 개선 과정
점진적인 레거시 웹 애플리케이션 개선 과정
 
Building Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJavaBuilding Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJava
 
Next generation message driven systems with Akka
Next generation message driven systems with AkkaNext generation message driven systems with Akka
Next generation message driven systems with Akka
 
Building Stateful Microservices With Akka
Building Stateful Microservices With AkkaBuilding Stateful Microservices With Akka
Building Stateful Microservices With Akka
 

Recently uploaded

WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksSoftradix Technologies
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024BookNet Canada
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024Neo4j
 

Recently uploaded (20)

WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other Frameworks
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
 
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptxVulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 

Declarative Concurrency with Reactive Programming

  • 1. Declarative Concurrency with Reactive Programming Florian Stefan | #ebaytechtalk
  • 2. 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
  • 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