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

More Related Content

What's hot

Introduction to Reactive programming
Introduction to Reactive programmingIntroduction to Reactive programming
Introduction to Reactive programming
Dwi Randy Herdinanto
 
Being Functional on Reactive Streams with Spring Reactor
Being Functional on Reactive Streams with Spring ReactorBeing Functional on Reactive Streams with Spring Reactor
Being Functional on Reactive Streams with Spring Reactor
Max Huang
 
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
Knoldus Inc.
 
Reactive Spring Framework 5
Reactive Spring Framework 5Reactive Spring Framework 5
Reactive Spring Framework 5
Aliaksei Zhynhiarouski
 
Reactive programming intro
Reactive programming introReactive programming intro
Reactive programming intro
Ahmed Ehab AbdulAziz
 
Understanding Reactive Programming
Understanding Reactive ProgrammingUnderstanding Reactive Programming
Understanding Reactive Programming
Andres Almiray
 
Reactive Programming in Java and Spring Framework 5
Reactive Programming in Java and Spring Framework 5Reactive Programming in Java and Spring Framework 5
Reactive Programming in Java and Spring Framework 5
Richard Langlois P. Eng.
 
SpringOne Tour: Spring Boot 3 and Beyond
SpringOne Tour: Spring Boot 3 and BeyondSpringOne Tour: Spring Boot 3 and Beyond
SpringOne Tour: Spring Boot 3 and Beyond
VMware Tanzu
 
AOT and Native with Spring Boot 3.0
AOT and Native with Spring Boot 3.0AOT and Native with Spring Boot 3.0
AOT and Native with Spring Boot 3.0
MoritzHalbritter
 
Vert.x for Microservices Architecture
Vert.x for Microservices ArchitectureVert.x for Microservices Architecture
Vert.x for Microservices Architecture
Idan Fridman
 
Reactive Web 101: WebFlux, WebClient, and Reactor Netty
Reactive Web 101: WebFlux, WebClient, and Reactor NettyReactive Web 101: WebFlux, WebClient, and Reactor Netty
Reactive Web 101: WebFlux, WebClient, and Reactor Netty
VMware Tanzu
 
Reactive Microservices with Quarkus
Reactive Microservices with QuarkusReactive Microservices with Quarkus
Reactive Microservices with Quarkus
Niklas Heidloff
 
Microservices with Java, Spring Boot and Spring Cloud
Microservices with Java, Spring Boot and Spring CloudMicroservices with Java, Spring Boot and Spring Cloud
Microservices with Java, Spring Boot and Spring Cloud
Eberhard Wolff
 
Spring Cloud Gateway
Spring Cloud GatewaySpring Cloud Gateway
Spring Cloud Gateway
Stéphane Maldini
 
Modeling Data and Queries for Wide Column NoSQL
Modeling Data and Queries for Wide Column NoSQLModeling Data and Queries for Wide Column NoSQL
Modeling Data and Queries for Wide Column NoSQL
ScyllaDB
 
Introduction to GraphQL
Introduction to GraphQLIntroduction to GraphQL
Introduction to GraphQL
Amazon Web Services
 
Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition!
Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition! Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition!
Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition!
Michel Schudel
 
Reactive programming with examples
Reactive programming with examplesReactive programming with examples
Reactive programming with examples
Peter Lawrey
 
GraalVM Overview Compact version
GraalVM Overview Compact versionGraalVM Overview Compact version
GraalVM Overview Compact version
scalaconfjp
 
Wars of MySQL Cluster ( InnoDB Cluster VS Galera )
Wars of MySQL Cluster ( InnoDB Cluster VS Galera ) Wars of MySQL Cluster ( InnoDB Cluster VS Galera )
Wars of MySQL Cluster ( InnoDB Cluster VS Galera )
Mydbops
 

What's hot (20)

Introduction to Reactive programming
Introduction to Reactive programmingIntroduction to Reactive programming
Introduction to Reactive programming
 
Being Functional on Reactive Streams with Spring Reactor
Being Functional on Reactive Streams with Spring ReactorBeing Functional on Reactive Streams with Spring Reactor
Being Functional on Reactive Streams with Spring Reactor
 
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
 
Reactive Spring Framework 5
Reactive Spring Framework 5Reactive Spring Framework 5
Reactive Spring Framework 5
 
Reactive programming intro
Reactive programming introReactive programming intro
Reactive programming intro
 
Understanding Reactive Programming
Understanding Reactive ProgrammingUnderstanding Reactive Programming
Understanding Reactive Programming
 
Reactive Programming in Java and Spring Framework 5
Reactive Programming in Java and Spring Framework 5Reactive Programming in Java and Spring Framework 5
Reactive Programming in Java and Spring Framework 5
 
SpringOne Tour: Spring Boot 3 and Beyond
SpringOne Tour: Spring Boot 3 and BeyondSpringOne Tour: Spring Boot 3 and Beyond
SpringOne Tour: Spring Boot 3 and Beyond
 
AOT and Native with Spring Boot 3.0
AOT and Native with Spring Boot 3.0AOT and Native with Spring Boot 3.0
AOT and Native with Spring Boot 3.0
 
Vert.x for Microservices Architecture
Vert.x for Microservices ArchitectureVert.x for Microservices Architecture
Vert.x for Microservices Architecture
 
Reactive Web 101: WebFlux, WebClient, and Reactor Netty
Reactive Web 101: WebFlux, WebClient, and Reactor NettyReactive Web 101: WebFlux, WebClient, and Reactor Netty
Reactive Web 101: WebFlux, WebClient, and Reactor Netty
 
Reactive Microservices with Quarkus
Reactive Microservices with QuarkusReactive Microservices with Quarkus
Reactive Microservices with Quarkus
 
Microservices with Java, Spring Boot and Spring Cloud
Microservices with Java, Spring Boot and Spring CloudMicroservices with Java, Spring Boot and Spring Cloud
Microservices with Java, Spring Boot and Spring Cloud
 
Spring Cloud Gateway
Spring Cloud GatewaySpring Cloud Gateway
Spring Cloud Gateway
 
Modeling Data and Queries for Wide Column NoSQL
Modeling Data and Queries for Wide Column NoSQLModeling Data and Queries for Wide Column NoSQL
Modeling Data and Queries for Wide Column NoSQL
 
Introduction to GraphQL
Introduction to GraphQLIntroduction to GraphQL
Introduction to GraphQL
 
Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition!
Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition! Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition!
Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition!
 
Reactive programming with examples
Reactive programming with examplesReactive programming with examples
Reactive programming with examples
 
GraalVM Overview Compact version
GraalVM Overview Compact versionGraalVM Overview Compact version
GraalVM Overview Compact version
 
Wars of MySQL Cluster ( InnoDB Cluster VS Galera )
Wars of MySQL Cluster ( InnoDB Cluster VS Galera ) Wars of MySQL Cluster ( InnoDB Cluster VS Galera )
Wars of MySQL Cluster ( InnoDB Cluster VS Galera )
 

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 Databases
Ivaylo 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 slowpokes
Sergey Tarasevich
 
Akka.NET streams and reactive streams
Akka.NET streams and reactive streamsAkka.NET streams and reactive streams
Akka.NET streams and reactive streams
Bartosz 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 RxJava
Matt Stine
 
Reactive java programming for the impatient
Reactive java programming for the impatientReactive java programming for the impatient
Reactive java programming for the impatient
Grant Steinfeld
 
Reactive programming for java developers
Reactive programming for java developersReactive programming for java developers
Reactive programming for java developers
Constantin Popa
 
Practical RxJava for Android
Practical RxJava for AndroidPractical RxJava for Android
Practical RxJava for Android
Tomáš 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 extensions
Oleksandr Zhevzhyk
 
Programming Sideways: Asynchronous Techniques for Android
Programming Sideways: Asynchronous Techniques for AndroidProgramming Sideways: Asynchronous Techniques for Android
Programming Sideways: Asynchronous Techniques for Android
Emanuele Di Saverio
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on Android
Tomáš Kypta
 
Asynchronous stream processing with Akka Streams
Asynchronous stream processing with Akka StreamsAsynchronous stream processing with Akka Streams
Asynchronous stream processing with Akka Streams
Johan Andrén
 
Productionalizing spark streaming applications
Productionalizing spark streaming applicationsProductionalizing spark streaming applications
Productionalizing spark streaming applications
Robert 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 Streams
Kevin 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 2
JollyRogers5
 
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
IndicThreads
 
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 RxJava
Rick 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 Akka
Johan Andrén
 
Building Stateful Microservices With Akka
Building Stateful Microservices With AkkaBuilding Stateful Microservices With Akka
Building Stateful Microservices With Akka
Yaroslav 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

UI5 Controls simplified - UI5con2024 presentation
UI5 Controls simplified - UI5con2024 presentationUI5 Controls simplified - UI5con2024 presentation
UI5 Controls simplified - UI5con2024 presentation
Wouter Lemaire
 
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy SurveyTrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc
 
Building Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and MilvusBuilding Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and Milvus
Zilliz
 
GraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracyGraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracy
Tomaz Bratanic
 
GenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizationsGenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizations
kumardaparthi1024
 
Choosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptxChoosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptx
Brandon Minnick, MBA
 
Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024
Jason Packer
 
Operating System Used by Users in day-to-day life.pptx
Operating System Used by Users in day-to-day life.pptxOperating System Used by Users in day-to-day life.pptx
Operating System Used by Users in day-to-day life.pptx
Pravash Chandra Das
 
5th LF Energy Power Grid Model Meet-up Slides
5th LF Energy Power Grid Model Meet-up Slides5th LF Energy Power Grid Model Meet-up Slides
5th LF Energy Power Grid Model Meet-up Slides
DanBrown980551
 
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdfUnlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Malak Abu Hammad
 
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdfHow to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
Chart Kalyan
 
Best 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERPBest 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERP
Pixlogix Infotech
 
Recommendation System using RAG Architecture
Recommendation System using RAG ArchitectureRecommendation System using RAG Architecture
Recommendation System using RAG Architecture
fredae14
 
HCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAUHCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAU
panagenda
 
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
alexjohnson7307
 
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
saastr
 
AWS Cloud Cost Optimization Presentation.pptx
AWS Cloud Cost Optimization Presentation.pptxAWS Cloud Cost Optimization Presentation.pptx
AWS Cloud Cost Optimization Presentation.pptx
HarisZaheer8
 
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Jeffrey Haguewood
 
Taking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdfTaking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdf
ssuserfac0301
 
dbms calicut university B. sc Cs 4th sem.pdf
dbms  calicut university B. sc Cs 4th sem.pdfdbms  calicut university B. sc Cs 4th sem.pdf
dbms calicut university B. sc Cs 4th sem.pdf
Shinana2
 

Recently uploaded (20)

UI5 Controls simplified - UI5con2024 presentation
UI5 Controls simplified - UI5con2024 presentationUI5 Controls simplified - UI5con2024 presentation
UI5 Controls simplified - UI5con2024 presentation
 
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy SurveyTrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy Survey
 
Building Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and MilvusBuilding Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and Milvus
 
GraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracyGraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracy
 
GenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizationsGenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizations
 
Choosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptxChoosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptx
 
Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024
 
Operating System Used by Users in day-to-day life.pptx
Operating System Used by Users in day-to-day life.pptxOperating System Used by Users in day-to-day life.pptx
Operating System Used by Users in day-to-day life.pptx
 
5th LF Energy Power Grid Model Meet-up Slides
5th LF Energy Power Grid Model Meet-up Slides5th LF Energy Power Grid Model Meet-up Slides
5th LF Energy Power Grid Model Meet-up Slides
 
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdfUnlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
 
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdfHow to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
 
Best 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERPBest 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERP
 
Recommendation System using RAG Architecture
Recommendation System using RAG ArchitectureRecommendation System using RAG Architecture
Recommendation System using RAG Architecture
 
HCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAUHCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAU
 
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
 
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
 
AWS Cloud Cost Optimization Presentation.pptx
AWS Cloud Cost Optimization Presentation.pptxAWS Cloud Cost Optimization Presentation.pptx
AWS Cloud Cost Optimization Presentation.pptx
 
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
 
Taking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdfTaking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdf
 
dbms calicut university B. sc Cs 4th sem.pdf
dbms  calicut university B. sc Cs 4th sem.pdfdbms  calicut university B. sc Cs 4th sem.pdf
dbms calicut university B. sc Cs 4th sem.pdf
 

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