SlideShare a Scribd company logo
1 of 35
Download to read offline
mindloops
RXJAVA: FROM THE TRENCHES
PETER HENDRIKS
@PETERHENDRIKS80
PETER@MINDLOOPS.NL
Agenda
• Intro
• Why we want RxJava
• RxJava in Practice
• Future / conclusion
What is ReactiveX?
“A library for composing asynchronous
and event-based programs by using observable
sequences” - Erik Meijer
What is RxJava?
• Port of ReactiveX C# framework to Java
• Open source, lead by Netflix
• 1.0.0 release november 2014, 2.0.0 last week :)
• ReactiveX is currently available in 14 programming languages
RxJava Survival Guide
// In your own code, convert results in a fluent way...

Observable<String> descriptionObservable = eventObservable.map(event -> event.getDescription());
// e.g. Database, services, keyboard, messaging etc.

MyEventProducer eventProducer = new MyEventProducer();
// use some custom adapter code to adapt to an RxJava "Observable"

Observable<MyEvent> eventObservable = eventProducer.toObservable();
// ... And compose with other Observables

Observable<Success> storeObservable = eventObservable.flatMap(event -> storeEvent(event));



private Observable<Success> storeEvent(MyEvent event) {

// stores the event asynchronously...

}
// Start flowing by subscribing and do something with final results
storeObservable.subscribe(myEvent -> {/* do something */}, error -> LOG.error("Oops", error));
Case: Sanoma Learning
• Web e-learning platform
• Many users
• Co-development: multiple
agile product teams
Case: Sanoma Learning
• AngularJS, Java 8, Vert.x,
MongoDB, AWS S3, Redis
• Suite of micro-services







Microservices met Vert.x
- Tim van Eindhoven, Zaal 4, 11:30
Why RxJava
WHY RXJAVA
Why we want RxJava
• Avoid “callback hell”
• Out of the box support
• Streaming performance benefits
Simplicity of the POJAM
• A simple, blocking Plain Old JAva Method
• Predictable execution flow
• Fully built-in result and error handling
• Easy to compose
public List<QuestionView> listQuestions(String studentId, String segmentId) {

List<Question> questions = contentService.findBySegmentId(segmentId);



List<QuestionView> result = new ArrayList<>();

for(Question question : questions) {

Progress progress = progressService.findByQuestionId(studentId, question.getId());

result.add(new QuestionView(question, progress));

}

return result;

}
Vert.x callback example
MessageConsumer<String> consumer = eventBus.consumer("news.uk.sport");

consumer.handler(message -> {

try {

System.out.println("I have received a message: " + message.body());

message.reply("how interesting!");

} catch (Exception e) {

message.fail(500, e.getMessage());

}

});



sendNewsMessage("Yay! Someone kicked a ball across a patch of grass", ar -> {

if (ar.succeeded()) {

System.out.println("Received reply: " + ar.result().body());

} else {

ar.cause().printStackTrace();

}

});
private void sendNewsMessage(String message, Handler<AsyncResult<Message<Object>>> replyHandler) {

eventBus.send("news.uk.sport", message, replyHandler);

}
Callback hell
void listQuestions(String studentId, String segmentId, Handler<AsyncResult<List<QuestionView>>> resultHandler) {

findBySegmentId(segmentId, ar -> {

if (ar.succeeded()) {

List<QuestionView> result = new ArrayList<>();

List<Question> questions = ar.result().body();

for(Question question : questions) {

findByQuestionId(studentId, question.getId(), progressAr -> {

if (ar.succeeded()) {

Progress progress = progressAr.result().body();

result.add(new QuestionView(question, progress));

questions.remove(question);

if (questions.isEmpty()) {

resultHandler.handle(Future.<List<QuestionView>>succeededFuture(result));

}

} else {

resultHandler.handle(Future.<List<QuestionView>>failedFuture(ar.cause()));

}

});

}

} else {

resultHandler.handle(Future.<List<QuestionView>>failedFuture(progressAr.cause()));

}

} );

}



private void findBySegmentId(String segmentId, Handler<AsyncResult<Message<List<Question>>>> handler) {}



private void findByQuestionId(String studentId, String questionId, Handler<AsyncResult<Message<Progress>>> handler) {}
Solution: RxJava as “Promise API”
public Observable<QuestionView> listQuestions(String studentId, String segmentId) {

return contentService.findBySegmentId(segmentId)

.concatMap(question -> progressService.findByQuestionId(studentId, question.getId())

.map(progress -> new QuestionView(question, progress)));

}
RxJava: one Promise API to rule them all
• We want to use one promise API
everywhere to fix callback hell
• RxJava is directly supported in Vert.x and
the MongoDB Java driver
Typical request processing overhead
Thread
Request
Response (List)
Domain data
(List)
public List<QuestionView> listQuestions(String studentId, String segmentId) {

List<Question> questions = contentService.findBySegmentId(segmentId);



List<Question> result = new ArrayList<>();

for(Question question : questions) {

Progress progress =
progressService.findByQuestionId(studentId, question.getId());

result.add(new QuestionView(question, progress));

}

return result;

}
Streaming == less intermediate data needed
public Observable<QuestionView> listQuestions(String studentId, String
segmentId) {

return contentService.findBySegmentId(segmentId)

.flatMap(question ->
progressService.findByQuestionId(studentId, question.getId())

.map(progress -> new QuestionView(question, progress)));

}
Thread
Request
Response (List)
Domain data
(element)
RXJAVA IN PRACTICE
Expect a learning curve
“Simple” promises vs RxJava
CompletableFuture Observable
What emits 1 event or 1 error emit 0 or more events and/or 1 error
When
Immediately scheduled for
execution
already executing, or only after
subscription
Where
Event can be read at any time
after completion
Event is available once
Learn to stream first!
• RxJava will force you to do it
• It helps to be comfortable with Java 8 Stream API first
• Java 8 Stream API still very useful for POJAM code
public Observable<QuestionView> listQuestions(String studentId, String segmentId) {

return contentService.findBySegmentId(segmentId)

.flatMap(question -> progressService.findByQuestionId(studentId, question.getId())

.map(progress -> new QuestionView(question, progress)));

}
Hot vs Cold Observables
// HOT

MyEventProducer eventProducer = new MyEventProducer();

// some other code...

Observable<MyEvent> hotObservable = Observable.create(subscriber -> {

// Listen to producer here.

});

hotObservable.subscribe(myEvent -> {/* do something with event */});
// COLD

Observable<MyEvent> coldObservable = Observable.create(subscriber -> {

MyEventProducer eventProducer = new MyEventProducer();

// Listen to producer here.

});

// some other code...

coldObservable.subscribe(myEvent -> {/* do something with event */});
Examples of hot and cold
// HOT example

HttpServer server = vertx.createHttpServer();

Observable<HttpServerRequest> requests = server.requestStream().toObservable();

// some other code

requests.subscribe(request -> System.out.println(request.absoluteURI()));
//COLD example

MongoClient mongoClient = MongoClients.create();

MongoCollection<Document> questionCollection =
mongoClient.getDatabase("contents").getCollection("questions");

Observable<Document> allQuestions = questionCollection.find().toObservable();

// some other code

allQuestions.subscribe(question -> System.out.println(question));
Always end with subscribe somewhere
// wrong way to check value
@Test

public void storeAnswerStoresAnswer() {

Observable<QuestionView> questionView = answerController.storeAnswer("1", "test");



questionView.map(view -> assertThat(view, is(testView)));

}
// use test subscriber to test observables in isolation
@Test

public void storeAnswerStoresAnswer() {

Observable<QuestionView> questionView = answerController.storeAnswer("1", "test");



TestSubscriber<QuestionView> ts = new TestSubscriber<>();

questionView.subscribe(ts);

ts.awaitTerminalEvent();

ts.assertNoErrors();

ts.assertValue(testValue);

}
0 or more events dilemma
// POJAM

public QuestionView storeAnswer(String questionId, String textValue) {

Question question = contentService.findByQuestionId(questionId);

if (question == null) {

throw new IllegalStateException("question not found");

}

Answer answer = validateAnswer(question, textValue);

progressService.store(questionId, answer);

return new QuestionView(question, answer);

}
// RxJava wrong

public Observable<QuestionView> storeAnswer(String questionId, String textValue) {

return contentService.findByQuestionId(questionId)

.flatMap(question -> {

Answer answer = validateAnswer(question, textValue);

return progressService.store(questionId, answer)

.map(x -> new QuestionView(question, answer));

});

}
// RxJava with switch

public Observable<QuestionView> storeAnswer(String questionId, String textValue) {

return contentService.findByQuestionId(questionId)

.switchIfEmpty(Observable.defer(() ->

Observable.error(new IllegalStateException("question not found"))))

.flatMap(question -> {

Answer answer = validateAnswer(question, textValue);

return progressService.store(questionId, answer)

.map(x -> new QuestionView(question, answer));

});

}
Mapping “always empty” results
public Observable<Void> storeResult(String answer) {

System.out.println("Do some async operation without result.");

return Observable.empty();

}



public Observable<String> processRequest(String answer) {

// This does not work right

return storeResult(answer)

.map(x -> "success!");

}
public interface MongoCollection<TDocument> {

/**

* @return an Observable with a single element indicating when the operation has completed
or with either a com.mongodb.DuplicateKeyException or com.mongodb.MongoException

*/

Observable<Success> insertOne(TDocument document);

}

// Return non-null event to be compatible with RxJava 2.x

public enum Success {

SUCCESS

}
Will change in RxJava 2.x
Better distinction between 0, 1,
optional and multiple results
Make it easy to do the right thing
Only use RxJava when needed
• POJAM code still the best for a lot of your code
• Use RxJava only for async composition/streaming
public boolean isAnswerCorrect(Question question, String answer) {

// some complicated synchronised checking logic here

return true;

}



public Observable<String> processRequest(String questionId, String answer) {

return contentService.findByQuestionId(questionId)

.map(question -> isAnswerCorrect(question, answer))

.map(result -> result ? "Good job!" : "Better luck next time!");

}
Separate subscribe code
• Separate and reuse subscribe code from observable chains
// BAD: subscription mixed with observable code

public void processRequest(HttpServerRequest request, String questionId, String answer) {

contentService.findByQuestionId(questionId)

.map(question -> isAnswerCorrect(question, answer))

.map(result -> result ? "Good job!" : "Better luck next time!")

.subscribe(result -> request.response().end(result));

}
// GOOD: simple observable code, easy to test and cannot forget to subscribe

public Observable<String> processRequest(String questionId, String answer) {

return contentService.findByQuestionId(questionId)

.map(question -> isAnswerCorrect(question, answer))

.map(result -> result ? "Good job!" : "Better luck next time!");

}
Async code and crappy stack traces
public static void main(String[] args) {

Observable.empty()

.observeOn(Schedulers.io())

.toBlocking()

.first();

}
Exception in thread "main" java.util.NoSuchElementException: Sequence contains no elements

at rx.internal.operators.OperatorSingle$ParentSubscriber.onCompleted(OperatorSingle.java:131)

at rx.internal.operators.OperatorTake$1.onCompleted(OperatorTake.java:53)

at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.pollQueue(OperatorObserveOn.java:195)

at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber$1.call(OperatorObserveOn.java:162)

at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)

at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)

at java.util.concurrent.FutureTask.run(FutureTask.java:266)

at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(<…>.java:180)

at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(<…>.java:293)

at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)

at java.lang.Thread.run(Thread.java:745)
Band-aid: add context to logging/exceptions
// generic wrapping code

public void processRequest(HttpServerRequest request,

Function<HttpServerRequest, Observable<String>> processor) {

Observable<String> observable = processor.apply(request);

observable.subscribe(

result -> processResult(request, result),

error -> processError(request, error));

}



private void processError(HttpServerRequest request, Throwable error) {

LOG.error("An error occurred processing: " + request.uri(), error);

request.response().setStatusCode(500).setStatusMessage(error.getMessage()).end();

}
FUTURE OF RXJAVA
The Future of RxJava looks promising
• Increased adoption for “Reactive Streams”
• RxJava 2 solves some API weirdness and simplifies simple event handling
• Strong adoption in Android and JavaScript
• Spring 5 goes big on reactive, including RxJava support
Spring example
@RestController

public class RxJavaController {

private final RxJavaService aService;

@Autowired

public RxJavaController(RxJavaService aService) {

this.aService = aService;

}

@RequestMapping(path = "/handleMessageRxJava", method = RequestMethod.POST)

public Observable<MessageAcknowledgement> handleMessage(@RequestBody Message message) {

System.out.println("Got Message..");

return this.aService.handleMessage(message);

}

}
RxJava 2.x
Reactive Streams
(Backpressure)
No Backpressure
0..n items,
complete, error
Flowable Observable
0..1 item, complete,
error
Maybe
1 item, error Single
complete, error Completable
CONCLUSION
RxJava in practice
- Learning to stream
- Hot vs Cold observables
- Always subscribe
- 0 or more events dilemma
- Dealing with always empty results Make it easy
- Still use POJAM code
- Separate subscribe code
- Make up for stack trace
Why we want RxJava
- Avoid Callback Hell
- Streaming helps performance
- Out of the box support
PETER HENDRIKS
@PETERHENDRIKS80
PETER@MINDLOOPS.NL

More Related Content

What's hot

Practical RxJava for Android
Practical RxJava for AndroidPractical RxJava for Android
Practical RxJava for AndroidTomáš Kypta
 
Introduction to Retrofit and RxJava
Introduction to Retrofit and RxJavaIntroduction to Retrofit and RxJava
Introduction to Retrofit and RxJavaFabio Collini
 
Building Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJavaBuilding Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJavaRick Warren
 
Streams, Streams Everywhere! An Introduction to Rx
Streams, Streams Everywhere! An Introduction to RxStreams, Streams Everywhere! An Introduction to Rx
Streams, Streams Everywhere! An Introduction to RxAndrzej Sitek
 
Intro to RxJava/RxAndroid - GDG Munich Android
Intro to RxJava/RxAndroid - GDG Munich AndroidIntro to RxJava/RxAndroid - GDG Munich Android
Intro to RxJava/RxAndroid - GDG Munich AndroidEgor Andreevich
 
Akka Actor presentation
Akka Actor presentationAkka Actor presentation
Akka Actor presentationGene Chang
 
RxJava for Android - GDG DevFest Ukraine 2015
RxJava for Android - GDG DevFest Ukraine 2015RxJava for Android - GDG DevFest Ukraine 2015
RxJava for Android - GDG DevFest Ukraine 2015Constantine Mars
 
Kotlin Receiver Types 介紹
Kotlin Receiver Types 介紹Kotlin Receiver Types 介紹
Kotlin Receiver Types 介紹Kros Huang
 
Android architecture component - FbCircleDev Yogyakarta Indonesia
Android architecture component - FbCircleDev Yogyakarta IndonesiaAndroid architecture component - FbCircleDev Yogyakarta Indonesia
Android architecture component - FbCircleDev Yogyakarta IndonesiaPratama Nur Wijaya
 
How to Think in RxJava Before Reacting
How to Think in RxJava Before ReactingHow to Think in RxJava Before Reacting
How to Think in RxJava Before ReactingIndicThreads
 
Reactive programming with RxAndroid
Reactive programming with RxAndroidReactive programming with RxAndroid
Reactive programming with RxAndroidSavvycom Savvycom
 
Non Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJavaNon Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJavaFrank Lyaruu
 
Reactive Programming in Java 8 with Rx-Java
Reactive Programming in Java 8 with Rx-JavaReactive Programming in Java 8 with Rx-Java
Reactive Programming in Java 8 with Rx-JavaKasun Indrasiri
 
Reactive Thinking in Java
Reactive Thinking in JavaReactive Thinking in Java
Reactive Thinking in JavaYakov Fain
 

What's hot (20)

Practical RxJava for Android
Practical RxJava for AndroidPractical RxJava for Android
Practical RxJava for Android
 
Introduction to Retrofit and RxJava
Introduction to Retrofit and RxJavaIntroduction to Retrofit and RxJava
Introduction to Retrofit and RxJava
 
Building Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJavaBuilding Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJava
 
Rx java in action
Rx java in actionRx java in action
Rx java in action
 
Streams, Streams Everywhere! An Introduction to Rx
Streams, Streams Everywhere! An Introduction to RxStreams, Streams Everywhere! An Introduction to Rx
Streams, Streams Everywhere! An Introduction to Rx
 
AWS Java SDK @ scale
AWS Java SDK @ scaleAWS Java SDK @ scale
AWS Java SDK @ scale
 
Reactive Java (33rd Degree)
Reactive Java (33rd Degree)Reactive Java (33rd Degree)
Reactive Java (33rd Degree)
 
Forgive me for i have allocated
Forgive me for i have allocatedForgive me for i have allocated
Forgive me for i have allocated
 
Intro to RxJava/RxAndroid - GDG Munich Android
Intro to RxJava/RxAndroid - GDG Munich AndroidIntro to RxJava/RxAndroid - GDG Munich Android
Intro to RxJava/RxAndroid - GDG Munich Android
 
RxJava Applied
RxJava AppliedRxJava Applied
RxJava Applied
 
Akka Actor presentation
Akka Actor presentationAkka Actor presentation
Akka Actor presentation
 
RxJava for Android - GDG DevFest Ukraine 2015
RxJava for Android - GDG DevFest Ukraine 2015RxJava for Android - GDG DevFest Ukraine 2015
RxJava for Android - GDG DevFest Ukraine 2015
 
Kotlin Receiver Types 介紹
Kotlin Receiver Types 介紹Kotlin Receiver Types 介紹
Kotlin Receiver Types 介紹
 
Android architecture component - FbCircleDev Yogyakarta Indonesia
Android architecture component - FbCircleDev Yogyakarta IndonesiaAndroid architecture component - FbCircleDev Yogyakarta Indonesia
Android architecture component - FbCircleDev Yogyakarta Indonesia
 
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
 
Reactive programming with RxAndroid
Reactive programming with RxAndroidReactive programming with RxAndroid
Reactive programming with RxAndroid
 
Non Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJavaNon Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJava
 
Reactive Programming in Java 8 with Rx-Java
Reactive Programming in Java 8 with Rx-JavaReactive Programming in Java 8 with Rx-Java
Reactive Programming in Java 8 with Rx-Java
 
RxJava on Android
RxJava on AndroidRxJava on Android
RxJava on Android
 
Reactive Thinking in Java
Reactive Thinking in JavaReactive Thinking in Java
Reactive Thinking in Java
 

Similar to RXJAVA: STREAMING PERFORMANCE BENEFITS

Mutation testing Bucharest Tech Week
Mutation testing Bucharest Tech WeekMutation testing Bucharest Tech Week
Mutation testing Bucharest Tech WeekPaco van Beckhoven
 
比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotationjavatwo2011
 
Ajax Under The Hood
Ajax Under The HoodAjax Under The Hood
Ajax Under The HoodWO Community
 
Improve unit tests with Mutants!
Improve unit tests with Mutants!Improve unit tests with Mutants!
Improve unit tests with Mutants!Paco van Beckhoven
 
Testdrevet javautvikling på objektorienterte skinner
Testdrevet javautvikling på objektorienterte skinnerTestdrevet javautvikling på objektorienterte skinner
Testdrevet javautvikling på objektorienterte skinnerTruls Jørgensen
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on AndroidTomáš Kypta
 
Reactive programming every day
Reactive programming every dayReactive programming every day
Reactive programming every dayVadym Khondar
 
MongoDB World 2019: Life In Stitch-es
MongoDB World 2019: Life In Stitch-esMongoDB World 2019: Life In Stitch-es
MongoDB World 2019: Life In Stitch-esMongoDB
 
EVERYTHING ABOUT STATIC CODE ANALYSIS FOR A JAVA PROGRAMMER
EVERYTHING ABOUT STATIC CODE ANALYSIS FOR A JAVA PROGRAMMEREVERYTHING ABOUT STATIC CODE ANALYSIS FOR A JAVA PROGRAMMER
EVERYTHING ABOUT STATIC CODE ANALYSIS FOR A JAVA PROGRAMMERAndrey Karpov
 
L2 Web App Development Guest Lecture At University of Surrey 20/11/09
L2 Web App Development Guest Lecture At University of Surrey 20/11/09L2 Web App Development Guest Lecture At University of Surrey 20/11/09
L2 Web App Development Guest Lecture At University of Surrey 20/11/09Daniel Bryant
 
React table tutorial project setup, use table, and usefilter
React table tutorial project setup, use table, and usefilterReact table tutorial project setup, use table, and usefilter
React table tutorial project setup, use table, and usefilterKaty Slemon
 
Introduction to Software Testing
Introduction to Software TestingIntroduction to Software Testing
Introduction to Software TestingSergio Arroyo
 
Testing, Performance Analysis, and jQuery 1.4
Testing, Performance Analysis, and jQuery 1.4Testing, Performance Analysis, and jQuery 1.4
Testing, Performance Analysis, and jQuery 1.4jeresig
 

Similar to RXJAVA: STREAMING PERFORMANCE BENEFITS (20)

Mutation testing Bucharest Tech Week
Mutation testing Bucharest Tech WeekMutation testing Bucharest Tech Week
Mutation testing Bucharest Tech Week
 
比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotation
 
Ajax Under The Hood
Ajax Under The HoodAjax Under The Hood
Ajax Under The Hood
 
Improve unit tests with Mutants!
Improve unit tests with Mutants!Improve unit tests with Mutants!
Improve unit tests with Mutants!
 
Testdrevet javautvikling på objektorienterte skinner
Testdrevet javautvikling på objektorienterte skinnerTestdrevet javautvikling på objektorienterte skinner
Testdrevet javautvikling på objektorienterte skinner
 
Javascript quiz
Javascript quizJavascript quiz
Javascript quiz
 
Rx workshop
Rx workshopRx workshop
Rx workshop
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on Android
 
Design for Testability
Design for TestabilityDesign for Testability
Design for Testability
 
Jason parsing
Jason parsingJason parsing
Jason parsing
 
Reactive programming every day
Reactive programming every dayReactive programming every day
Reactive programming every day
 
MongoDB World 2019: Life In Stitch-es
MongoDB World 2019: Life In Stitch-esMongoDB World 2019: Life In Stitch-es
MongoDB World 2019: Life In Stitch-es
 
EVERYTHING ABOUT STATIC CODE ANALYSIS FOR A JAVA PROGRAMMER
EVERYTHING ABOUT STATIC CODE ANALYSIS FOR A JAVA PROGRAMMEREVERYTHING ABOUT STATIC CODE ANALYSIS FOR A JAVA PROGRAMMER
EVERYTHING ABOUT STATIC CODE ANALYSIS FOR A JAVA PROGRAMMER
 
L2 Web App Development Guest Lecture At University of Surrey 20/11/09
L2 Web App Development Guest Lecture At University of Surrey 20/11/09L2 Web App Development Guest Lecture At University of Surrey 20/11/09
L2 Web App Development Guest Lecture At University of Surrey 20/11/09
 
React table tutorial project setup, use table, and usefilter
React table tutorial project setup, use table, and usefilterReact table tutorial project setup, use table, and usefilter
React table tutorial project setup, use table, and usefilter
 
Struts2 - 101
Struts2 - 101Struts2 - 101
Struts2 - 101
 
Introduction to Software Testing
Introduction to Software TestingIntroduction to Software Testing
Introduction to Software Testing
 
Testing, Performance Analysis, and jQuery 1.4
Testing, Performance Analysis, and jQuery 1.4Testing, Performance Analysis, and jQuery 1.4
Testing, Performance Analysis, and jQuery 1.4
 
D3_Tuto_GD
D3_Tuto_GDD3_Tuto_GD
D3_Tuto_GD
 
D3_Tuto_GD
D3_Tuto_GDD3_Tuto_GD
D3_Tuto_GD
 

Recently uploaded

chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptkotipi9215
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about usDynamic Netsoft
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
Engage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyEngage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyFrank van der Linden
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...gurkirankumar98700
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
XpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software SolutionsXpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software SolutionsMehedi Hasan Shohan
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...aditisharan08
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - InfographicHr365.us smith
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfjoe51371421
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWave PLM
 
The Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfThe Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfPower Karaoke
 
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝soniya singh
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 

Recently uploaded (20)

chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.ppt
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about us
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Engage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyEngage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The Ugly
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
XpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software SolutionsXpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software Solutions
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - Infographic
 
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdf
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need It
 
The Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfThe Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdf
 
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 

RXJAVA: STREAMING PERFORMANCE BENEFITS

  • 1. mindloops RXJAVA: FROM THE TRENCHES PETER HENDRIKS @PETERHENDRIKS80 PETER@MINDLOOPS.NL
  • 2. Agenda • Intro • Why we want RxJava • RxJava in Practice • Future / conclusion
  • 3. What is ReactiveX? “A library for composing asynchronous and event-based programs by using observable sequences” - Erik Meijer
  • 4. What is RxJava? • Port of ReactiveX C# framework to Java • Open source, lead by Netflix • 1.0.0 release november 2014, 2.0.0 last week :) • ReactiveX is currently available in 14 programming languages
  • 5. RxJava Survival Guide // In your own code, convert results in a fluent way...
 Observable<String> descriptionObservable = eventObservable.map(event -> event.getDescription()); // e.g. Database, services, keyboard, messaging etc.
 MyEventProducer eventProducer = new MyEventProducer(); // use some custom adapter code to adapt to an RxJava "Observable"
 Observable<MyEvent> eventObservable = eventProducer.toObservable(); // ... And compose with other Observables
 Observable<Success> storeObservable = eventObservable.flatMap(event -> storeEvent(event));
 
 private Observable<Success> storeEvent(MyEvent event) {
 // stores the event asynchronously...
 } // Start flowing by subscribing and do something with final results storeObservable.subscribe(myEvent -> {/* do something */}, error -> LOG.error("Oops", error));
  • 6. Case: Sanoma Learning • Web e-learning platform • Many users • Co-development: multiple agile product teams
  • 7. Case: Sanoma Learning • AngularJS, Java 8, Vert.x, MongoDB, AWS S3, Redis • Suite of micro-services
 
 
 
 Microservices met Vert.x - Tim van Eindhoven, Zaal 4, 11:30
  • 9. Why we want RxJava • Avoid “callback hell” • Out of the box support • Streaming performance benefits
  • 10. Simplicity of the POJAM • A simple, blocking Plain Old JAva Method • Predictable execution flow • Fully built-in result and error handling • Easy to compose public List<QuestionView> listQuestions(String studentId, String segmentId) {
 List<Question> questions = contentService.findBySegmentId(segmentId);
 
 List<QuestionView> result = new ArrayList<>();
 for(Question question : questions) {
 Progress progress = progressService.findByQuestionId(studentId, question.getId());
 result.add(new QuestionView(question, progress));
 }
 return result;
 }
  • 11. Vert.x callback example MessageConsumer<String> consumer = eventBus.consumer("news.uk.sport");
 consumer.handler(message -> {
 try {
 System.out.println("I have received a message: " + message.body());
 message.reply("how interesting!");
 } catch (Exception e) {
 message.fail(500, e.getMessage());
 }
 });
 
 sendNewsMessage("Yay! Someone kicked a ball across a patch of grass", ar -> {
 if (ar.succeeded()) {
 System.out.println("Received reply: " + ar.result().body());
 } else {
 ar.cause().printStackTrace();
 }
 }); private void sendNewsMessage(String message, Handler<AsyncResult<Message<Object>>> replyHandler) {
 eventBus.send("news.uk.sport", message, replyHandler);
 }
  • 12. Callback hell void listQuestions(String studentId, String segmentId, Handler<AsyncResult<List<QuestionView>>> resultHandler) {
 findBySegmentId(segmentId, ar -> {
 if (ar.succeeded()) {
 List<QuestionView> result = new ArrayList<>();
 List<Question> questions = ar.result().body();
 for(Question question : questions) {
 findByQuestionId(studentId, question.getId(), progressAr -> {
 if (ar.succeeded()) {
 Progress progress = progressAr.result().body();
 result.add(new QuestionView(question, progress));
 questions.remove(question);
 if (questions.isEmpty()) {
 resultHandler.handle(Future.<List<QuestionView>>succeededFuture(result));
 }
 } else {
 resultHandler.handle(Future.<List<QuestionView>>failedFuture(ar.cause()));
 }
 });
 }
 } else {
 resultHandler.handle(Future.<List<QuestionView>>failedFuture(progressAr.cause()));
 }
 } );
 }
 
 private void findBySegmentId(String segmentId, Handler<AsyncResult<Message<List<Question>>>> handler) {}
 
 private void findByQuestionId(String studentId, String questionId, Handler<AsyncResult<Message<Progress>>> handler) {}
  • 13. Solution: RxJava as “Promise API” public Observable<QuestionView> listQuestions(String studentId, String segmentId) {
 return contentService.findBySegmentId(segmentId)
 .concatMap(question -> progressService.findByQuestionId(studentId, question.getId())
 .map(progress -> new QuestionView(question, progress)));
 }
  • 14. RxJava: one Promise API to rule them all • We want to use one promise API everywhere to fix callback hell • RxJava is directly supported in Vert.x and the MongoDB Java driver
  • 15. Typical request processing overhead Thread Request Response (List) Domain data (List) public List<QuestionView> listQuestions(String studentId, String segmentId) {
 List<Question> questions = contentService.findBySegmentId(segmentId);
 
 List<Question> result = new ArrayList<>();
 for(Question question : questions) {
 Progress progress = progressService.findByQuestionId(studentId, question.getId());
 result.add(new QuestionView(question, progress));
 }
 return result;
 }
  • 16. Streaming == less intermediate data needed public Observable<QuestionView> listQuestions(String studentId, String segmentId) {
 return contentService.findBySegmentId(segmentId)
 .flatMap(question -> progressService.findByQuestionId(studentId, question.getId())
 .map(progress -> new QuestionView(question, progress)));
 } Thread Request Response (List) Domain data (element)
  • 19. “Simple” promises vs RxJava CompletableFuture Observable What emits 1 event or 1 error emit 0 or more events and/or 1 error When Immediately scheduled for execution already executing, or only after subscription Where Event can be read at any time after completion Event is available once
  • 20. Learn to stream first! • RxJava will force you to do it • It helps to be comfortable with Java 8 Stream API first • Java 8 Stream API still very useful for POJAM code public Observable<QuestionView> listQuestions(String studentId, String segmentId) {
 return contentService.findBySegmentId(segmentId)
 .flatMap(question -> progressService.findByQuestionId(studentId, question.getId())
 .map(progress -> new QuestionView(question, progress)));
 }
  • 21. Hot vs Cold Observables // HOT
 MyEventProducer eventProducer = new MyEventProducer();
 // some other code...
 Observable<MyEvent> hotObservable = Observable.create(subscriber -> {
 // Listen to producer here.
 });
 hotObservable.subscribe(myEvent -> {/* do something with event */}); // COLD
 Observable<MyEvent> coldObservable = Observable.create(subscriber -> {
 MyEventProducer eventProducer = new MyEventProducer();
 // Listen to producer here.
 });
 // some other code...
 coldObservable.subscribe(myEvent -> {/* do something with event */});
  • 22. Examples of hot and cold // HOT example
 HttpServer server = vertx.createHttpServer();
 Observable<HttpServerRequest> requests = server.requestStream().toObservable();
 // some other code
 requests.subscribe(request -> System.out.println(request.absoluteURI())); //COLD example
 MongoClient mongoClient = MongoClients.create();
 MongoCollection<Document> questionCollection = mongoClient.getDatabase("contents").getCollection("questions");
 Observable<Document> allQuestions = questionCollection.find().toObservable();
 // some other code
 allQuestions.subscribe(question -> System.out.println(question));
  • 23. Always end with subscribe somewhere // wrong way to check value @Test
 public void storeAnswerStoresAnswer() {
 Observable<QuestionView> questionView = answerController.storeAnswer("1", "test");
 
 questionView.map(view -> assertThat(view, is(testView)));
 } // use test subscriber to test observables in isolation @Test
 public void storeAnswerStoresAnswer() {
 Observable<QuestionView> questionView = answerController.storeAnswer("1", "test");
 
 TestSubscriber<QuestionView> ts = new TestSubscriber<>();
 questionView.subscribe(ts);
 ts.awaitTerminalEvent();
 ts.assertNoErrors();
 ts.assertValue(testValue);
 }
  • 24. 0 or more events dilemma // POJAM
 public QuestionView storeAnswer(String questionId, String textValue) {
 Question question = contentService.findByQuestionId(questionId);
 if (question == null) {
 throw new IllegalStateException("question not found");
 }
 Answer answer = validateAnswer(question, textValue);
 progressService.store(questionId, answer);
 return new QuestionView(question, answer);
 } // RxJava wrong
 public Observable<QuestionView> storeAnswer(String questionId, String textValue) {
 return contentService.findByQuestionId(questionId)
 .flatMap(question -> {
 Answer answer = validateAnswer(question, textValue);
 return progressService.store(questionId, answer)
 .map(x -> new QuestionView(question, answer));
 });
 } // RxJava with switch
 public Observable<QuestionView> storeAnswer(String questionId, String textValue) {
 return contentService.findByQuestionId(questionId)
 .switchIfEmpty(Observable.defer(() ->
 Observable.error(new IllegalStateException("question not found"))))
 .flatMap(question -> {
 Answer answer = validateAnswer(question, textValue);
 return progressService.store(questionId, answer)
 .map(x -> new QuestionView(question, answer));
 });
 }
  • 25. Mapping “always empty” results public Observable<Void> storeResult(String answer) {
 System.out.println("Do some async operation without result.");
 return Observable.empty();
 }
 
 public Observable<String> processRequest(String answer) {
 // This does not work right
 return storeResult(answer)
 .map(x -> "success!");
 } public interface MongoCollection<TDocument> {
 /**
 * @return an Observable with a single element indicating when the operation has completed or with either a com.mongodb.DuplicateKeyException or com.mongodb.MongoException
 */
 Observable<Success> insertOne(TDocument document);
 }
 // Return non-null event to be compatible with RxJava 2.x
 public enum Success {
 SUCCESS
 } Will change in RxJava 2.x Better distinction between 0, 1, optional and multiple results
  • 26. Make it easy to do the right thing
  • 27. Only use RxJava when needed • POJAM code still the best for a lot of your code • Use RxJava only for async composition/streaming public boolean isAnswerCorrect(Question question, String answer) {
 // some complicated synchronised checking logic here
 return true;
 }
 
 public Observable<String> processRequest(String questionId, String answer) {
 return contentService.findByQuestionId(questionId)
 .map(question -> isAnswerCorrect(question, answer))
 .map(result -> result ? "Good job!" : "Better luck next time!");
 }
  • 28. Separate subscribe code • Separate and reuse subscribe code from observable chains // BAD: subscription mixed with observable code
 public void processRequest(HttpServerRequest request, String questionId, String answer) {
 contentService.findByQuestionId(questionId)
 .map(question -> isAnswerCorrect(question, answer))
 .map(result -> result ? "Good job!" : "Better luck next time!")
 .subscribe(result -> request.response().end(result));
 } // GOOD: simple observable code, easy to test and cannot forget to subscribe
 public Observable<String> processRequest(String questionId, String answer) {
 return contentService.findByQuestionId(questionId)
 .map(question -> isAnswerCorrect(question, answer))
 .map(result -> result ? "Good job!" : "Better luck next time!");
 }
  • 29. Async code and crappy stack traces public static void main(String[] args) {
 Observable.empty()
 .observeOn(Schedulers.io())
 .toBlocking()
 .first();
 } Exception in thread "main" java.util.NoSuchElementException: Sequence contains no elements
 at rx.internal.operators.OperatorSingle$ParentSubscriber.onCompleted(OperatorSingle.java:131)
 at rx.internal.operators.OperatorTake$1.onCompleted(OperatorTake.java:53)
 at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.pollQueue(OperatorObserveOn.java:195)
 at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber$1.call(OperatorObserveOn.java:162)
 at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
 at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
 at java.util.concurrent.FutureTask.run(FutureTask.java:266)
 at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(<…>.java:180)
 at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(<…>.java:293)
 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
 at java.lang.Thread.run(Thread.java:745)
  • 30. Band-aid: add context to logging/exceptions // generic wrapping code
 public void processRequest(HttpServerRequest request,
 Function<HttpServerRequest, Observable<String>> processor) {
 Observable<String> observable = processor.apply(request);
 observable.subscribe(
 result -> processResult(request, result),
 error -> processError(request, error));
 }
 
 private void processError(HttpServerRequest request, Throwable error) {
 LOG.error("An error occurred processing: " + request.uri(), error);
 request.response().setStatusCode(500).setStatusMessage(error.getMessage()).end();
 }
  • 32. The Future of RxJava looks promising • Increased adoption for “Reactive Streams” • RxJava 2 solves some API weirdness and simplifies simple event handling • Strong adoption in Android and JavaScript • Spring 5 goes big on reactive, including RxJava support
  • 33. Spring example @RestController
 public class RxJavaController {
 private final RxJavaService aService;
 @Autowired
 public RxJavaController(RxJavaService aService) {
 this.aService = aService;
 }
 @RequestMapping(path = "/handleMessageRxJava", method = RequestMethod.POST)
 public Observable<MessageAcknowledgement> handleMessage(@RequestBody Message message) {
 System.out.println("Got Message..");
 return this.aService.handleMessage(message);
 }
 }
  • 34. RxJava 2.x Reactive Streams (Backpressure) No Backpressure 0..n items, complete, error Flowable Observable 0..1 item, complete, error Maybe 1 item, error Single complete, error Completable
  • 35. CONCLUSION RxJava in practice - Learning to stream - Hot vs Cold observables - Always subscribe - 0 or more events dilemma - Dealing with always empty results Make it easy - Still use POJAM code - Separate subscribe code - Make up for stack trace Why we want RxJava - Avoid Callback Hell - Streaming helps performance - Out of the box support PETER HENDRIKS @PETERHENDRIKS80 PETER@MINDLOOPS.NL