Reactive solutions
using
Java 9 & Spring’s Reactor
Speaker: Oren Ezer
session flow
• Abstract concept
• Java 9 additions
• Write a java 9 simple impl
• Spring Reactor overview
• Write a Spring Reactor implementations using Spring Boot
• WebFlux overview
• Write an E2E WebFlux app (with or without UI)
Reactive Streams
Reactive Streams - concept
• Many times blocking code is wasteful
• Concurrency and parallelizm are good but usually requires more resources
• Is Async code the solution?
• Threading are not good enough / easy enough to code
• Callbacks, Futures and even CompetableFuture are not good enough
• Pull was not good enough - blocking or simply wasting resources
• Push was not good enough - “suffocating” the consumer
• Pull-Push was the solution
• Overall throughput vs. single request performance
Reactive Streams - concept
• Simpler code, making it more readable.
• Abstracts away from
• Boilerplate code --> focus on business logic.
• Low-level threading, synchronization, and concurrency issues.
• Stream processing implies memory efficient
• The model can be applied almost everywhere, both in-memory as well as
over protocols like http, to solve almost any kind of problem.
• Reactive Streams vs. Java Streams
• Flow of elements with operations between flow parts
• Subscriber will initiate processing
• Async vs. sync
Reactive Streams - concept
From the spec:
Reactive Streams is an initiative to provide a standard for asynchronous
stream processing with non-blocking back pressure. This encompasses
efforts aimed at runtime environments (JVM and JavaScript) as well as
network protocols.
Reactive Streams - characteristics
• Elastic
• The system stays responsive under varying workload.
• Reactive Systems can react to changes in the input rate by increasing or
decreasing the resources allocated to service these inputs.
• Implies an ability to replicate components and split inputs among them.
• Predictive/Reactive scaling algorithms supported by relevant live
performance measures.
• Resilient
• The system stay responsive in case of failures
• Failures are contained in each isolated component
• High availability is achieved by replication where needed
Reactive Streams - characteristics
• Responsive
• The system responds in a timely manner if at all possible
• Implies that problems are detected quickly and dealt with effectively.
• Rapid and consistent response times (consistent service quality)
• Message Driven
• Reactive Systems rely on asynchronous message-passing
to establish a boundary between components
• Implies load management, elasticity, and flow control by monitoring the
message queues
• Back-pressure and failure delegation
Reactive Streams - semantics
• A Concept to deal with synchronous/asynchronous stream
processing with non-blocking back-pressure.
(notifying producers of data to reduce their message rate.)
• Processing might be synchronous or asynchronous but it shines
on the “communication” UCs
• Consumers are in control of the Data Flow
Reactive in Java 9
Interfaces
• The Java 9 addition is java.util.concurrent.Flow interface
• Publisher – the producer of elements.
• Subscriber – the handler of elements.
• Subscription - the specific Publisher-Subscriber binding
• Processor – a typical node in a reactive “chain” essentially consumes
elements from previous node and produces elements to the next one
• 1:1 semantic equivalism between Java APIs and their respective
Reactive Streams counterparts.
• org.reactivestreams.FlowAdapters to gap between reactive streams
interfaces and java 9 Flow interfaces
Interfaces
Subscriber
Subscription
Publisher
Call onSubscribe() with the new Subscription
Creates a new
Subscription for the
new Subscriber’s
interactions
Call subscribe() to start interactions
- Handshake
Interfaces
Subscriber
Subscription
Publisher
- Interaction
Call request() for
specifying the amount of
requested “activations”
Call onNext() with the next element
Interfaces
Subscriber
Subscription
Publisher
- Disengaging
Publisher failed or
finished
Call onError() or onComplete() accordingly
Call cancel() to signal
the Subscription that it
is terminated and that
the Subscription is
revoked
Subscriber must not call
any Subscription/Publisher
methods after it was
signaled for complete/error
Call cancel() on
unrecoverable failure
or if the Subscription
is no longer needed or
if onSubscribe() is
called when an active
Subscription is
already inplace
Call onError() on
unrecoverable failure
of the Subscription
Interfaces
• Publisher – the producer. Provides a single method: subscribe().
• Subscriber – subscribes to a Producer. Has the following methods:
• onSubscribe – will be invoked before any other method.
• onNext – invoked with the next item to process.
• onError – unrecoverable error, no more methods will be invoked on this
instance.
• onComplete – no additional data will be receive (last method to be
invoked).
Interfaces
• Subscription – provided to the onSubscribe invocation.
Provides the following methods:
• request(n) – demands n more elements from the producer.
• cancel – best effort method to cancel the subscription.
• Processor – implements both Producer and Subscriber.
• Publisher/Subscription/Subscriber/Processor—
all methods defined by these interfaces return “void”
to support asynchronicity
Reactive Streams
• The JDK doesn’t provide implementations for reactive-streams
interfaces.
• Available popular implementations:
• Project Reactor – used by Spring 5.
• Akka Streams.
• RxJava.
• Vert.x.
• Slick.
• MongoDB Java driver.
• Reactive Rabbit (RabbitMQ).
• Ratpack.
Flow interface - exercise 1
• Implement a naive solution for Flow interfaces
• Publisher
• Subscriber
• Subscription
• Impl should be minimal - ex. printing the msg you are given
• Stick to the required API impl and avoid internal impl.
• Add a main() for running your solution
Flow interface - exercise 2
• Change your solution to use SubmissionPublisher
• Add Processor impl and chain it to the flow.
• Impl should be minimal - ex. altering the msg you are given
• Stick to the required API impl and avoid internal impl.
• Run your flow and verify both subscriptions are working
Internal semantics
• Subscriber’s buffer bounds are known & controlled by the subscribers
• Back-pressure is mandatory so the use of unbounded buffers can be
avoided
• Publisher must respect Subscriber’s limits. It can either
• buffer exceeding elements
• drop exceeding elements.
• Maximum number of elements that may arrive = P-B-N
(until more demand is signaled to the Publisher)
• P - total number of elements requested
• B - number of elements B in its input buffer
• N - number of elements that have been processed
Reactor
Reactor semantics
• Mono and Flux are implementations of Publisher
• The assembly line metaphor
• The “belt”
• The raw materials pouring on it
• The workstations - introducing transformation, might be overloaded
• The end product ready to be consumed
• Multiple operators as part of the fluent API
• Cold vs. Hot publishers
Reactor - Code examples
• Creating a simple Mono / Flux
Flux<Integer> numbers = Flux.range(9, 27);
Flux<Person> flux = Flux.fromArray(array);
Flux<Integer> flux = Flux.fromIterable(list);
Flux<Tweet> flux = Flux.fromStream(stream);
• Simple Mono / Flux with a simple subscriber
Flux.just("a", "b", "c")
.subscribe((s)->System.out.println(s));
Reactor - Code examples
• Flux/Mono docs including diagrams
• Creating a Flux using generate()
Flux<UUID> uuids = Flux.generate(
(sink)->sink.next(UUID.randomUUID()));
• Creating a Flux using create()
Flux<Person> flux = Flux.create();
We will see more about create() soon...
Reactor exercise - Clock 1
• Create a “ticker”
• Generate a flow of values representing the time
• Print second’s ticks to the console
Reactor - Code examples
• Verifying / Filtering flux data using operators
Mono<Boolean> mono = flux.any(predicate);
Mono<Boolean> mono = flux.all(predicate);
Mono<Boolean> mono = flux.hasElement(myObject);
Flux<String> filtered = stringsFlux.filter(predicate);
Reactor exercise - Clock 2
• Change your “ticker”
• To show only 10 second’s ticks
• To finish after 20 ticks.
• Display a “closing statement” for your flux
• Try to implement it using create() …..
Reactor exercise - Clock 3
• Change your “ticker”
• To use the state supplier for the time increment
Reactor - Code examples
• Creating a “heartbeat” Flux using interval() and a Duration
Flux<Long> intervals=Flux.interval(Duration.ofSeconds(2))
• Creating a “join” point for multiple publishers
Mono<Void> joinPoint = Mono.when(publisher1, pub2, p3);
• Creating special publishers
Mono<Integer> empty = Mono.empty();
Flux<String> nothing = Flux.never();
Reactor - Code examples
• Combining fluxs using merge()
Flux<Integer> nums = Flux.merge(evens, odds);
• Combining fluxs using concat()
Flux<Integer> nums = Flux.concat(lows, highs);
• Combining fluxs using zip()
Flux<Tuple2<Integer,Integer>> colunmValue =
Flux.zip(lefts, rights);
• Same goes for xxxWith() methods:
evens.mergeWith(odds);
lows.concatWith(highs);
lefts.zipWith(rights);
Reactor - Code examples
• Flux transformation using operators
Iterator iterator = flux.toIterable().iterator();
Flux<String> strings = Flux.range(3, 33).map((n)->""+n);
• Combining fluxs using zip() and map() operators
Flux<String> fullNames = Flux.zip(titles, first, last)
.map(t->t.getT1()+" "+t.getT2()+"
"+t.getT3());
Reactor exercise - Clock 4
• Change your “ticker”
• use interval()
• Use zipWith to achieve the same “ticking” functionality
Reactor - Code examples
• Combining fluxs using zip() for throttling the data flow:
Flux<Long> delay =
Flux.interval(Duration.ofMillis(500));
Flux<String> pacedFlux=dataFlux.zipWith(delay,(d,l)-
>d);
• extracting flux data using blocking operators w/o duration
Mono<Person> person = mono.block();
Mono<Person> person = flux.blockFirst(timeoutDuration);
Mono<Person> person = flux.blockLast();
Spring & Reactive Streams
Spring Data Repos Spring Data Reactive Repos
Servlet container
(Tomcat, Jetty, etc.)
NIO Runtime
(Netty, servlet 3.1, etc.)
Spring MVC Spring Web Flux
Spring Reactive Security
Spring Boot
Spring Security
Spring 5 / Boot 2 - offering for reactive
• Reactor
• Spring MVC
• Flux/ Mono support in controllers
• Handler / Router functions
• Reactive data stores (Mongo, Redis, Casandra)
• WebFlux starter and Netty as default
• Multiple WebSocketClients for Netty, undertow, etc.
Spring 5 / Reactor - Testing
• StepVerifier
• WebClient
• Client side reactive end point
• Its API is working with publishers and subscribers
• Both on the response side but also on the request side (building the body)
• Filtering and strategies are available too
• Error handling using onStatus()
• WebTestClient
• For unit testing specific handlers or routes
• For E2E integration tests with real server
• TCK - Reactive Streams Technology Compatibility Kit
• V1
• Generate a stream of stock quotes (make sure to throttle)
• Use WebFlux to expose this stream over HTTP
• Use WebClient and SSE media type
• V2
• Generate a stream of stock quotes (make sure to throttle)
• Use reactive MongDB to store this stream in mogo
• “Proove” stocks keep flowing into mongo using you WebClient
• V3
• Reactively consume the data from Mongo
• Use WebClient to consume your stocks endpoints
• Try to keep it coming…..
• V4
• Add a filter to retrieve stocks by symbol name
• Change to hot stream
Reactive - exercises - "Stocks"
Spring 5 / Reactor - Threading
• Publishers and Subscriber are not dealing with threads.
Operators are dealing with them instead.
• Dealing with threading by selecting the type of Scheduler you are
using
• Schedulers are used to publishOn(), subscribeOn(), cancelOn()
• publishOn() applies down stream whereas subscribeOn() applies up stream
• Flux.range(1, 100).publishOn(Schedulers.parallel());
• Flux.interval(Duration.ofMillis(10), Schedulers.newSingle("dedicatedOne"));
• You should handle blocking calls in a specific way
• Mono wrapBlockingCode = Mono.fromCallable(() -> {
return /* blocking synchronous call */
});
wrapedBlockingCode = wrapBlockingCode.subscribeOn(Schedulers.elastic());
Spring 5 / Reactor - downsides
• Harder to debug
• Easy to add blocking code while fixing something
• Most of the traditional integration libraries are still blocking
• Limited options for Reactive data stores
• Spring Security is still not supported.
• Typical UCs that are good
candidates for reactive solutions:
• Handling high rate of external
transactions (stocks, financial, etc.)
• Logging
• UI events
• Sensor’s metrics
• IoT readings
• Let’s see a typical UC from
the domain of UI event
handling
From: https://gist.github.com/staltz/868e7e9bc2a7b8c1f754
Summary
• The hardest part is thinking in Reactive
• let go of imperative / stateful habits of typical programming
• forcing your brain to work in a different paradigm
• Instead of "X changes Y" go for "Y is changed by X".
• Reactive Programming is programming with asynchronous data streams
• Never block
• Always handle your exceptions
• You observe these streams and react when a value is emitted.
• Separation of concerns is fundamental to function chaining
• Immutability of streams is fundamental too
• “Who to follow suggestion” (based on the idea from: https://gist.github.com/staltz/868e7e9bc2a7b8c1f754)
• FE track - implement a suggestion window / popup
• Fetch GitHub users (or any other API from https://github.com/toddmotto/public-apis)
• Support selecting/ removing a specific suggestion
• Support selecting / removing a specific suggestion
• Add the relevant page for rendering the suggestions
• BE track - implement RESTful API
• Schedule the fetch of GitHub users
• Persist users in MongoDB
• Retrieve users using a REST controller
• Use WebClient / WebTestClient to consume your API
• Make sure you render/list only 10 users at a time
• Support ‘refresh’ functionality to replace the 10 retrieved users
(make sure you don’t “lose” users and you don’t re-fetch them)
• Take care of extreme cases like initialization for example
Summary exercise
Relevant Links
• https://dzone.com/articles/spring-webflux-getting-started
• https://ordina-jworks.github.io/reactive/2016/12/12/Reactive-
Programming-Spring-Reactor.html
• https://github.com/iproduct/spring-5-webflux
• https://docs.spring.io/spring/docs/5.0.0.BUILD-
SNAPSHOT/spring-framework-reference/html/web-
reactive.html
• http://www.baeldung.com/spring-reactor
• https://www.callicoder.com/reactive-rest-apis-spring-webflux-
reactive-mongo/
• https://thepracticaldeveloper.com/2017/11/04/full-reactive-
stack-with-spring-webflux-and-angularjs/
More relevant Links
● Download JDK 9
● JDK 9 Flow API javadoc
● Reactive Streams Specification
● Reactive Streams API javadoc
● The Reactive Manifesto
● https://community.oracle.com/docs/DOC-1006738
● https://projectreactor.io/docs/
● https://dzone.com/articles/doing-stuff-with-spring-webflux
● http://www.baeldung.com/spring-5-functional-web
● https://docs.spring.io/spring/docs/5.0.0.BUILD-SNAPSHOT/spring-
framework-reference/html/web-reactive.html

Reactive solutions using java 9 and spring reactor

  • 1.
    Reactive solutions using Java 9& Spring’s Reactor Speaker: Oren Ezer
  • 2.
    session flow • Abstractconcept • Java 9 additions • Write a java 9 simple impl • Spring Reactor overview • Write a Spring Reactor implementations using Spring Boot • WebFlux overview • Write an E2E WebFlux app (with or without UI)
  • 3.
  • 4.
    Reactive Streams -concept • Many times blocking code is wasteful • Concurrency and parallelizm are good but usually requires more resources • Is Async code the solution? • Threading are not good enough / easy enough to code • Callbacks, Futures and even CompetableFuture are not good enough • Pull was not good enough - blocking or simply wasting resources • Push was not good enough - “suffocating” the consumer • Pull-Push was the solution • Overall throughput vs. single request performance
  • 5.
    Reactive Streams -concept • Simpler code, making it more readable. • Abstracts away from • Boilerplate code --> focus on business logic. • Low-level threading, synchronization, and concurrency issues. • Stream processing implies memory efficient • The model can be applied almost everywhere, both in-memory as well as over protocols like http, to solve almost any kind of problem. • Reactive Streams vs. Java Streams • Flow of elements with operations between flow parts • Subscriber will initiate processing • Async vs. sync
  • 6.
    Reactive Streams -concept From the spec: Reactive Streams is an initiative to provide a standard for asynchronous stream processing with non-blocking back pressure. This encompasses efforts aimed at runtime environments (JVM and JavaScript) as well as network protocols.
  • 7.
    Reactive Streams -characteristics • Elastic • The system stays responsive under varying workload. • Reactive Systems can react to changes in the input rate by increasing or decreasing the resources allocated to service these inputs. • Implies an ability to replicate components and split inputs among them. • Predictive/Reactive scaling algorithms supported by relevant live performance measures. • Resilient • The system stay responsive in case of failures • Failures are contained in each isolated component • High availability is achieved by replication where needed
  • 8.
    Reactive Streams -characteristics • Responsive • The system responds in a timely manner if at all possible • Implies that problems are detected quickly and dealt with effectively. • Rapid and consistent response times (consistent service quality) • Message Driven • Reactive Systems rely on asynchronous message-passing to establish a boundary between components • Implies load management, elasticity, and flow control by monitoring the message queues • Back-pressure and failure delegation
  • 9.
    Reactive Streams -semantics • A Concept to deal with synchronous/asynchronous stream processing with non-blocking back-pressure. (notifying producers of data to reduce their message rate.) • Processing might be synchronous or asynchronous but it shines on the “communication” UCs • Consumers are in control of the Data Flow
  • 10.
  • 11.
    Interfaces • The Java9 addition is java.util.concurrent.Flow interface • Publisher – the producer of elements. • Subscriber – the handler of elements. • Subscription - the specific Publisher-Subscriber binding • Processor – a typical node in a reactive “chain” essentially consumes elements from previous node and produces elements to the next one • 1:1 semantic equivalism between Java APIs and their respective Reactive Streams counterparts. • org.reactivestreams.FlowAdapters to gap between reactive streams interfaces and java 9 Flow interfaces
  • 12.
    Interfaces Subscriber Subscription Publisher Call onSubscribe() withthe new Subscription Creates a new Subscription for the new Subscriber’s interactions Call subscribe() to start interactions - Handshake
  • 13.
    Interfaces Subscriber Subscription Publisher - Interaction Call request()for specifying the amount of requested “activations” Call onNext() with the next element
  • 14.
    Interfaces Subscriber Subscription Publisher - Disengaging Publisher failedor finished Call onError() or onComplete() accordingly Call cancel() to signal the Subscription that it is terminated and that the Subscription is revoked Subscriber must not call any Subscription/Publisher methods after it was signaled for complete/error Call cancel() on unrecoverable failure or if the Subscription is no longer needed or if onSubscribe() is called when an active Subscription is already inplace Call onError() on unrecoverable failure of the Subscription
  • 15.
    Interfaces • Publisher –the producer. Provides a single method: subscribe(). • Subscriber – subscribes to a Producer. Has the following methods: • onSubscribe – will be invoked before any other method. • onNext – invoked with the next item to process. • onError – unrecoverable error, no more methods will be invoked on this instance. • onComplete – no additional data will be receive (last method to be invoked).
  • 16.
    Interfaces • Subscription –provided to the onSubscribe invocation. Provides the following methods: • request(n) – demands n more elements from the producer. • cancel – best effort method to cancel the subscription. • Processor – implements both Producer and Subscriber. • Publisher/Subscription/Subscriber/Processor— all methods defined by these interfaces return “void” to support asynchronicity
  • 17.
    Reactive Streams • TheJDK doesn’t provide implementations for reactive-streams interfaces. • Available popular implementations: • Project Reactor – used by Spring 5. • Akka Streams. • RxJava. • Vert.x. • Slick. • MongoDB Java driver. • Reactive Rabbit (RabbitMQ). • Ratpack.
  • 18.
    Flow interface -exercise 1 • Implement a naive solution for Flow interfaces • Publisher • Subscriber • Subscription • Impl should be minimal - ex. printing the msg you are given • Stick to the required API impl and avoid internal impl. • Add a main() for running your solution
  • 19.
    Flow interface -exercise 2 • Change your solution to use SubmissionPublisher • Add Processor impl and chain it to the flow. • Impl should be minimal - ex. altering the msg you are given • Stick to the required API impl and avoid internal impl. • Run your flow and verify both subscriptions are working
  • 20.
    Internal semantics • Subscriber’sbuffer bounds are known & controlled by the subscribers • Back-pressure is mandatory so the use of unbounded buffers can be avoided • Publisher must respect Subscriber’s limits. It can either • buffer exceeding elements • drop exceeding elements. • Maximum number of elements that may arrive = P-B-N (until more demand is signaled to the Publisher) • P - total number of elements requested • B - number of elements B in its input buffer • N - number of elements that have been processed
  • 21.
  • 22.
    Reactor semantics • Monoand Flux are implementations of Publisher • The assembly line metaphor • The “belt” • The raw materials pouring on it • The workstations - introducing transformation, might be overloaded • The end product ready to be consumed • Multiple operators as part of the fluent API • Cold vs. Hot publishers
  • 23.
    Reactor - Codeexamples • Creating a simple Mono / Flux Flux<Integer> numbers = Flux.range(9, 27); Flux<Person> flux = Flux.fromArray(array); Flux<Integer> flux = Flux.fromIterable(list); Flux<Tweet> flux = Flux.fromStream(stream); • Simple Mono / Flux with a simple subscriber Flux.just("a", "b", "c") .subscribe((s)->System.out.println(s));
  • 24.
    Reactor - Codeexamples • Flux/Mono docs including diagrams • Creating a Flux using generate() Flux<UUID> uuids = Flux.generate( (sink)->sink.next(UUID.randomUUID())); • Creating a Flux using create() Flux<Person> flux = Flux.create(); We will see more about create() soon...
  • 25.
    Reactor exercise -Clock 1 • Create a “ticker” • Generate a flow of values representing the time • Print second’s ticks to the console
  • 26.
    Reactor - Codeexamples • Verifying / Filtering flux data using operators Mono<Boolean> mono = flux.any(predicate); Mono<Boolean> mono = flux.all(predicate); Mono<Boolean> mono = flux.hasElement(myObject); Flux<String> filtered = stringsFlux.filter(predicate);
  • 27.
    Reactor exercise -Clock 2 • Change your “ticker” • To show only 10 second’s ticks • To finish after 20 ticks. • Display a “closing statement” for your flux • Try to implement it using create() …..
  • 28.
    Reactor exercise -Clock 3 • Change your “ticker” • To use the state supplier for the time increment
  • 29.
    Reactor - Codeexamples • Creating a “heartbeat” Flux using interval() and a Duration Flux<Long> intervals=Flux.interval(Duration.ofSeconds(2)) • Creating a “join” point for multiple publishers Mono<Void> joinPoint = Mono.when(publisher1, pub2, p3); • Creating special publishers Mono<Integer> empty = Mono.empty(); Flux<String> nothing = Flux.never();
  • 30.
    Reactor - Codeexamples • Combining fluxs using merge() Flux<Integer> nums = Flux.merge(evens, odds); • Combining fluxs using concat() Flux<Integer> nums = Flux.concat(lows, highs); • Combining fluxs using zip() Flux<Tuple2<Integer,Integer>> colunmValue = Flux.zip(lefts, rights); • Same goes for xxxWith() methods: evens.mergeWith(odds); lows.concatWith(highs); lefts.zipWith(rights);
  • 31.
    Reactor - Codeexamples • Flux transformation using operators Iterator iterator = flux.toIterable().iterator(); Flux<String> strings = Flux.range(3, 33).map((n)->""+n); • Combining fluxs using zip() and map() operators Flux<String> fullNames = Flux.zip(titles, first, last) .map(t->t.getT1()+" "+t.getT2()+" "+t.getT3());
  • 32.
    Reactor exercise -Clock 4 • Change your “ticker” • use interval() • Use zipWith to achieve the same “ticking” functionality
  • 33.
    Reactor - Codeexamples • Combining fluxs using zip() for throttling the data flow: Flux<Long> delay = Flux.interval(Duration.ofMillis(500)); Flux<String> pacedFlux=dataFlux.zipWith(delay,(d,l)- >d); • extracting flux data using blocking operators w/o duration Mono<Person> person = mono.block(); Mono<Person> person = flux.blockFirst(timeoutDuration); Mono<Person> person = flux.blockLast();
  • 34.
    Spring & ReactiveStreams Spring Data Repos Spring Data Reactive Repos Servlet container (Tomcat, Jetty, etc.) NIO Runtime (Netty, servlet 3.1, etc.) Spring MVC Spring Web Flux Spring Reactive Security Spring Boot Spring Security
  • 35.
    Spring 5 /Boot 2 - offering for reactive • Reactor • Spring MVC • Flux/ Mono support in controllers • Handler / Router functions • Reactive data stores (Mongo, Redis, Casandra) • WebFlux starter and Netty as default • Multiple WebSocketClients for Netty, undertow, etc.
  • 36.
    Spring 5 /Reactor - Testing • StepVerifier • WebClient • Client side reactive end point • Its API is working with publishers and subscribers • Both on the response side but also on the request side (building the body) • Filtering and strategies are available too • Error handling using onStatus() • WebTestClient • For unit testing specific handlers or routes • For E2E integration tests with real server • TCK - Reactive Streams Technology Compatibility Kit
  • 37.
    • V1 • Generatea stream of stock quotes (make sure to throttle) • Use WebFlux to expose this stream over HTTP • Use WebClient and SSE media type • V2 • Generate a stream of stock quotes (make sure to throttle) • Use reactive MongDB to store this stream in mogo • “Proove” stocks keep flowing into mongo using you WebClient • V3 • Reactively consume the data from Mongo • Use WebClient to consume your stocks endpoints • Try to keep it coming….. • V4 • Add a filter to retrieve stocks by symbol name • Change to hot stream Reactive - exercises - "Stocks"
  • 38.
    Spring 5 /Reactor - Threading • Publishers and Subscriber are not dealing with threads. Operators are dealing with them instead. • Dealing with threading by selecting the type of Scheduler you are using • Schedulers are used to publishOn(), subscribeOn(), cancelOn() • publishOn() applies down stream whereas subscribeOn() applies up stream • Flux.range(1, 100).publishOn(Schedulers.parallel()); • Flux.interval(Duration.ofMillis(10), Schedulers.newSingle("dedicatedOne")); • You should handle blocking calls in a specific way • Mono wrapBlockingCode = Mono.fromCallable(() -> { return /* blocking synchronous call */ }); wrapedBlockingCode = wrapBlockingCode.subscribeOn(Schedulers.elastic());
  • 39.
    Spring 5 /Reactor - downsides • Harder to debug • Easy to add blocking code while fixing something • Most of the traditional integration libraries are still blocking • Limited options for Reactive data stores • Spring Security is still not supported.
  • 40.
    • Typical UCsthat are good candidates for reactive solutions: • Handling high rate of external transactions (stocks, financial, etc.) • Logging • UI events • Sensor’s metrics • IoT readings • Let’s see a typical UC from the domain of UI event handling From: https://gist.github.com/staltz/868e7e9bc2a7b8c1f754
  • 41.
    Summary • The hardestpart is thinking in Reactive • let go of imperative / stateful habits of typical programming • forcing your brain to work in a different paradigm • Instead of "X changes Y" go for "Y is changed by X". • Reactive Programming is programming with asynchronous data streams • Never block • Always handle your exceptions • You observe these streams and react when a value is emitted. • Separation of concerns is fundamental to function chaining • Immutability of streams is fundamental too
  • 42.
    • “Who tofollow suggestion” (based on the idea from: https://gist.github.com/staltz/868e7e9bc2a7b8c1f754) • FE track - implement a suggestion window / popup • Fetch GitHub users (or any other API from https://github.com/toddmotto/public-apis) • Support selecting/ removing a specific suggestion • Support selecting / removing a specific suggestion • Add the relevant page for rendering the suggestions • BE track - implement RESTful API • Schedule the fetch of GitHub users • Persist users in MongoDB • Retrieve users using a REST controller • Use WebClient / WebTestClient to consume your API • Make sure you render/list only 10 users at a time • Support ‘refresh’ functionality to replace the 10 retrieved users (make sure you don’t “lose” users and you don’t re-fetch them) • Take care of extreme cases like initialization for example Summary exercise
  • 43.
    Relevant Links • https://dzone.com/articles/spring-webflux-getting-started •https://ordina-jworks.github.io/reactive/2016/12/12/Reactive- Programming-Spring-Reactor.html • https://github.com/iproduct/spring-5-webflux • https://docs.spring.io/spring/docs/5.0.0.BUILD- SNAPSHOT/spring-framework-reference/html/web- reactive.html • http://www.baeldung.com/spring-reactor • https://www.callicoder.com/reactive-rest-apis-spring-webflux- reactive-mongo/ • https://thepracticaldeveloper.com/2017/11/04/full-reactive- stack-with-spring-webflux-and-angularjs/
  • 44.
    More relevant Links ●Download JDK 9 ● JDK 9 Flow API javadoc ● Reactive Streams Specification ● Reactive Streams API javadoc ● The Reactive Manifesto ● https://community.oracle.com/docs/DOC-1006738 ● https://projectreactor.io/docs/ ● https://dzone.com/articles/doing-stuff-with-spring-webflux ● http://www.baeldung.com/spring-5-functional-web ● https://docs.spring.io/spring/docs/5.0.0.BUILD-SNAPSHOT/spring- framework-reference/html/web-reactive.html