SlideShare a Scribd company logo
1 of 30
RxJava Applied:
Concise Examples where It Shines
Igor Lozynskyi
JEEConf - May 20-21, 2016
Software Engineer at GlobalLogic
Presentation’s home
https://github.com/aigor/rx-presentation
Modern apps
Created with draw.io
Options to deal with integration complexity
JDeferred
CompletableFuture<T>
Scala.Rx
Scala Actors
RxJava
RxJava
http://reactivex.io
https://github.com/ReactiveX/RxJava
Short history
● From 2009 for .NET
● From 2013 for JVM (latest: 1.1.5, May 5, 2016)
● Now a lot of other languages
Use case: Stream of tweets
Created with Balsamiq Mockups
Twitter API
Twitter Stream API (WebSocket alike):
● Doc: https://dev.twitter.com/streaming/overview
● Library: com.twitter:hbc-core:2.2.0
Twitter REST API:
● GET https://api.twitter.com/1.1/users/show.json?screen_name=jeeconf
● GET https://api.twitter.com/1.1/search/tweets.json?q=from:jeeconf
Observer
interface Observer<T> {
void onNext(T t);
void onCompleted();
void onError(Throwable e);
}
Observable
.create(s -> {
s.onNext("A");
s.onNext("B");
s.onCompleted();
})
.subscribe(m -> log.info("Message received: " + m),
e -> log.warning("Error: " + e.getMessage()),
() -> log.info("Done!"));
Output:
Message received: A
Message received: B
Done!
Let’s look at entities
class Tweet {
String text;
int favorite_count;
String author;
int author_followers;
}
class Profile {
String screen_name;
String name;
String location;
int statuses_count;
int followers_count;
}
class UserWithTweet {
Profile profile;
Tweet tweet;
}
Marble diagram
Profile getUserProfile(String screenName) {
ObjectMapper om = new ObjectMapper();
return (Profile) om.readValue(om.readTree(
Unirest.get(API_BASE_URL + "users/show.json")
.queryString("screen_name", screenName)
.header("Authorization", bearerAuth(authToken.get()))
.asString()
.getBody()),
Profile.class);
}
Get user profile synchronously
Get user profile asynchronously
Observable<Profile> getUserProfile(String screenName) {
return Observable.fromCallable(() -> {
ObjectMapper om = new ObjectMapper();
return (Profile) om.readValue(om.readTree(
Unirest.get(API_BASE_URL + "users/show.json")
.queryString("screen_name", screenName)
.header("Authorization", bearerAuth(authToken.get()))
.asString()
.getBody()),
Profile.class);
});
}
Add some errors handling
Observable<Profile> getUserProfile(String screenName) {
if (authToken.isPresent()) {
return Observable.fromCallable(() -> {
ObjectMapper om = new ObjectMapper();
return (Profile) om.readValue(om.readTree(
Unirest.get(API_BASE_URL + "users/show.json")
.queryString("screen_name", screenName)
.header("Authorization", bearerAuth(authToken.get()))
.asString()
.getBody()),
Profile.class);
}).doOnCompleted(() -> log("getUserProfile completed for: " + screenName));
} else {
return Observable.error(new RuntimeException("Can not connect to twitter"));
}
}
Let’s do something concurrently
Illustration: Arsenal Firearms S.r.l.
Get data concurrently
Observable<UserWithTweet> getUserAndPopularTweet(String author){
return Observable.just(author)
.flatMap(u -> {
Observable<Profile> profile = client.getUserProfile(u)
.subscribeOn(Schedulers.io());
Observable<Tweet> tweet = client.getUserRecentTweets(u)
.defaultIfEmpty(null)
.reduce((t1, t2) ->
t1.retweet_count > t2.retweet_count ? t1 : t2)
.subscribeOn(Schedulers.io());
return Observable.zip(profile, tweet, UserWithTweet::new);
});
}
Let’s subscribe on stream of tweets!
streamClient.getStream("RxJava", "JEEConf", "Java")
streamClient.getStream("RxJava", "JEEConf", "Java", "Trump")
streamClient.getStream("RxJava", "JEEConf", "Java", "Trump")
.distinctUntilChanged()
.map(p -> p.author)
.flatMap(name -> getUserAndPopularTweet(name))
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.immediate())
.subscribe(p -> log.info("The most popular tweet of user "
+ p.profile.name + ": " + p.tweet));
.scan((u1, u2) -> u1.author_followers > u2.author_followers ? u1 : u2)
streamClient.getStream("RxJava", "JEEConf", "Java", "Trump")
.scan((u1, u2) -> u1.author_followers > u2.author_followers ? u1 : u2)
.distinctUntilChanged()
.map(p -> p.author)
.flatMap(name -> {
Observable<Profile> profile = client.getUserProfile(name)
.subscribeOn(Schedulers.io());
Observable<Tweet> tweet = client.getUserRecentTweets(name)
.defaultIfEmpty(null)
.reduce((t1, t2) ->
t1.retweet_count > t2.retweet_count ? t1 : t2)
.subscribeOn(Schedulers.io());
return Observable.zip(profile, tweet, UserWithTweet::new);
})
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.immediate())
.subscribe(p -> log.info("The most popular tweet of user "
+ p.profile.name + ": " + p.tweet));
Marble diagram
▸ API is big (150+ methods to remember)
▸ Requires to understand underlying magic
▸ Hard to debug
▸ Don’t forget about back pressure
Conclusions: pitfalls
▸ It is functional, it is reactive*
▸ Good for integration scenarios
▸ Allows to control execution threads
▸ Easy to compose workflows
▸ Easy to integrate into existing solutions
▸ Easy to test
* RxJava is inspired by FRP (Functional Reactive Programming), but doesn’t implement it
Conclusions: strength
Q&A
Thanks
Presentation template by SlidesCarnival
@siromaha
aigooor@gmail.com

More Related Content

What's hot

What's hot (20)

Practical RxJava for Android
Practical RxJava for AndroidPractical RxJava for Android
Practical RxJava for Android
 
Reactive Java (GeeCON 2014)
Reactive Java (GeeCON 2014)Reactive Java (GeeCON 2014)
Reactive Java (GeeCON 2014)
 
Reactive Thinking in Java
Reactive Thinking in JavaReactive Thinking in Java
Reactive Thinking in Java
 
An Introduction to RxJava
An Introduction to RxJavaAn Introduction to RxJava
An Introduction to RxJava
 
rx-java-presentation
rx-java-presentationrx-java-presentation
rx-java-presentation
 
RxJava on Android
RxJava on AndroidRxJava on Android
RxJava on Android
 
Practical RxJava for Android
Practical RxJava for AndroidPractical RxJava for Android
Practical RxJava for Android
 
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
 
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
 
Introduction to rx java for android
Introduction to rx java for androidIntroduction to rx java for android
Introduction to rx java for android
 
Rx java in action
Rx java in actionRx java in action
Rx java in action
 
Reactive Programming on Android - RxAndroid - RxJava
Reactive Programming on Android - RxAndroid - RxJavaReactive Programming on Android - RxAndroid - RxJava
Reactive Programming on Android - RxAndroid - 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 2.0 介紹
RxJava 2.0 介紹RxJava 2.0 介紹
RxJava 2.0 介紹
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on Android
 
Rxjava 介紹與 Android 中的 RxJava
Rxjava 介紹與 Android 中的 RxJavaRxjava 介紹與 Android 中的 RxJava
Rxjava 介紹與 Android 中的 RxJava
 
Real world functional reactive programming
Real world functional reactive programmingReal world functional reactive programming
Real world functional reactive programming
 
RxJava in practice
RxJava in practice RxJava in practice
RxJava in practice
 
Introduction to Retrofit and RxJava
Introduction to Retrofit and RxJavaIntroduction to Retrofit and RxJava
Introduction to Retrofit and RxJava
 
Functional Reactive Programming in Clojurescript
Functional Reactive Programming in ClojurescriptFunctional Reactive Programming in Clojurescript
Functional Reactive Programming in Clojurescript
 

Viewers also liked (7)

04 pig data operations
04 pig data operations04 pig data operations
04 pig data operations
 
Play with play!
Play with play!Play with play!
Play with play!
 
So various polymorphism in Scala
So various polymorphism in ScalaSo various polymorphism in Scala
So various polymorphism in Scala
 
Issues in knowledge representation
Issues in knowledge representationIssues in knowledge representation
Issues in knowledge representation
 
Intro to Graph Databases Using Tinkerpop, TitanDB, and Gremlin
Intro to Graph Databases Using Tinkerpop, TitanDB, and GremlinIntro to Graph Databases Using Tinkerpop, TitanDB, and Gremlin
Intro to Graph Databases Using Tinkerpop, TitanDB, and Gremlin
 
Knowledge representation in AI
Knowledge representation in AIKnowledge representation in AI
Knowledge representation in AI
 
Knowledge representation and Predicate logic
Knowledge representation and Predicate logicKnowledge representation and Predicate logic
Knowledge representation and Predicate logic
 

Similar to RxJava Applied

Reactive & Realtime Web Applications with TurboGears2
Reactive & Realtime Web Applications with TurboGears2Reactive & Realtime Web Applications with TurboGears2
Reactive & Realtime Web Applications with TurboGears2
Alessandro Molina
 

Similar to RxJava Applied (20)

Reactive database access with Slick3
Reactive database access with Slick3Reactive database access with Slick3
Reactive database access with Slick3
 
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...
 
.NET Fest 2018. Антон Молдован. One year of using F# in production at SBTech
.NET Fest 2018. Антон Молдован. One year of using F# in production at SBTech.NET Fest 2018. Антон Молдован. One year of using F# in production at SBTech
.NET Fest 2018. Антон Молдован. One year of using F# in production at SBTech
 
Data visualization in python/Django
Data visualization in python/DjangoData visualization in python/Django
Data visualization in python/Django
 
Project Reactor Now and Tomorrow
Project Reactor Now and TomorrowProject Reactor Now and Tomorrow
Project Reactor Now and Tomorrow
 
Java Libraries You Can’t Afford to Miss
Java Libraries You Can’t Afford to Miss Java Libraries You Can’t Afford to Miss
Java Libraries You Can’t Afford to Miss
 
Reactive Functional Programming with Java 8 on Android N
Reactive Functional Programming with Java 8 on Android NReactive Functional Programming with Java 8 on Android N
Reactive Functional Programming with Java 8 on Android N
 
Full Stack Reactive with React and Spring WebFlux - Switzerland JUG 2020
Full Stack Reactive with React and Spring WebFlux - Switzerland JUG 2020Full Stack Reactive with React and Spring WebFlux - Switzerland JUG 2020
Full Stack Reactive with React and Spring WebFlux - Switzerland JUG 2020
 
Introduction to Spring WebFlux #jsug #sf_a1
Introduction to Spring WebFlux #jsug #sf_a1Introduction to Spring WebFlux #jsug #sf_a1
Introduction to Spring WebFlux #jsug #sf_a1
 
Reactive & Realtime Web Applications with TurboGears2
Reactive & Realtime Web Applications with TurboGears2Reactive & Realtime Web Applications with TurboGears2
Reactive & Realtime Web Applications with TurboGears2
 
Full Stack Reactive with React and Spring WebFlux - SpringOne 2018
Full Stack Reactive with React and Spring WebFlux - SpringOne 2018Full Stack Reactive with React and Spring WebFlux - SpringOne 2018
Full Stack Reactive with React and Spring WebFlux - SpringOne 2018
 
Intro to Akka Streams
Intro to Akka StreamsIntro to Akka Streams
Intro to Akka Streams
 
eBay Pulsar: Real-time analytics platform
eBay Pulsar: Real-time analytics platformeBay Pulsar: Real-time analytics platform
eBay Pulsar: Real-time analytics platform
 
Lambda Chops - Recipes for Simpler, More Expressive Code
Lambda Chops - Recipes for Simpler, More Expressive CodeLambda Chops - Recipes for Simpler, More Expressive Code
Lambda Chops - Recipes for Simpler, More Expressive Code
 
Reactive, component 그리고 angular2
Reactive, component 그리고  angular2Reactive, component 그리고  angular2
Reactive, component 그리고 angular2
 
RxJava2 Slides
RxJava2 SlidesRxJava2 Slides
RxJava2 Slides
 
IPT Reactive Java IoT Demo - BGOUG 2018
IPT Reactive Java IoT Demo - BGOUG 2018IPT Reactive Java IoT Demo - BGOUG 2018
IPT Reactive Java IoT Demo - BGOUG 2018
 
Choose Your Own Adventure with JHipster & Kubernetes - Denver JUG 2020
Choose Your Own Adventure with JHipster & Kubernetes - Denver JUG 2020Choose Your Own Adventure with JHipster & Kubernetes - Denver JUG 2020
Choose Your Own Adventure with JHipster & Kubernetes - Denver JUG 2020
 
UniRx - Reactive Extensions for Unity(EN)
UniRx - Reactive Extensions for Unity(EN)UniRx - Reactive Extensions for Unity(EN)
UniRx - Reactive Extensions for Unity(EN)
 
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディングXitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
 

Recently uploaded

%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
masabamasaba
 
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Medical / Health Care (+971588192166) Mifepristone and Misoprostol tablets 200mg
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
shinachiaurasa2
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
VictoriaMetrics
 

Recently uploaded (20)

W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go Platformless
 
Artyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxArtyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptx
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 

RxJava Applied

  • 1. RxJava Applied: Concise Examples where It Shines Igor Lozynskyi JEEConf - May 20-21, 2016 Software Engineer at GlobalLogic
  • 4. Options to deal with integration complexity JDeferred CompletableFuture<T> Scala.Rx Scala Actors RxJava
  • 6. Short history ● From 2009 for .NET ● From 2013 for JVM (latest: 1.1.5, May 5, 2016) ● Now a lot of other languages
  • 7. Use case: Stream of tweets Created with Balsamiq Mockups
  • 8. Twitter API Twitter Stream API (WebSocket alike): ● Doc: https://dev.twitter.com/streaming/overview ● Library: com.twitter:hbc-core:2.2.0 Twitter REST API: ● GET https://api.twitter.com/1.1/users/show.json?screen_name=jeeconf ● GET https://api.twitter.com/1.1/search/tweets.json?q=from:jeeconf
  • 9. Observer interface Observer<T> { void onNext(T t); void onCompleted(); void onError(Throwable e); }
  • 10. Observable .create(s -> { s.onNext("A"); s.onNext("B"); s.onCompleted(); }) .subscribe(m -> log.info("Message received: " + m), e -> log.warning("Error: " + e.getMessage()), () -> log.info("Done!")); Output: Message received: A Message received: B Done!
  • 11. Let’s look at entities class Tweet { String text; int favorite_count; String author; int author_followers; } class Profile { String screen_name; String name; String location; int statuses_count; int followers_count; } class UserWithTweet { Profile profile; Tweet tweet; }
  • 13. Profile getUserProfile(String screenName) { ObjectMapper om = new ObjectMapper(); return (Profile) om.readValue(om.readTree( Unirest.get(API_BASE_URL + "users/show.json") .queryString("screen_name", screenName) .header("Authorization", bearerAuth(authToken.get())) .asString() .getBody()), Profile.class); } Get user profile synchronously
  • 14. Get user profile asynchronously Observable<Profile> getUserProfile(String screenName) { return Observable.fromCallable(() -> { ObjectMapper om = new ObjectMapper(); return (Profile) om.readValue(om.readTree( Unirest.get(API_BASE_URL + "users/show.json") .queryString("screen_name", screenName) .header("Authorization", bearerAuth(authToken.get())) .asString() .getBody()), Profile.class); }); }
  • 15. Add some errors handling Observable<Profile> getUserProfile(String screenName) { if (authToken.isPresent()) { return Observable.fromCallable(() -> { ObjectMapper om = new ObjectMapper(); return (Profile) om.readValue(om.readTree( Unirest.get(API_BASE_URL + "users/show.json") .queryString("screen_name", screenName) .header("Authorization", bearerAuth(authToken.get())) .asString() .getBody()), Profile.class); }).doOnCompleted(() -> log("getUserProfile completed for: " + screenName)); } else { return Observable.error(new RuntimeException("Can not connect to twitter")); } }
  • 16. Let’s do something concurrently Illustration: Arsenal Firearms S.r.l.
  • 17.
  • 18. Get data concurrently Observable<UserWithTweet> getUserAndPopularTweet(String author){ return Observable.just(author) .flatMap(u -> { Observable<Profile> profile = client.getUserProfile(u) .subscribeOn(Schedulers.io()); Observable<Tweet> tweet = client.getUserRecentTweets(u) .defaultIfEmpty(null) .reduce((t1, t2) -> t1.retweet_count > t2.retweet_count ? t1 : t2) .subscribeOn(Schedulers.io()); return Observable.zip(profile, tweet, UserWithTweet::new); }); }
  • 19.
  • 20. Let’s subscribe on stream of tweets!
  • 23. streamClient.getStream("RxJava", "JEEConf", "Java", "Trump") .distinctUntilChanged() .map(p -> p.author) .flatMap(name -> getUserAndPopularTweet(name)) .subscribeOn(Schedulers.io()) .observeOn(Schedulers.immediate()) .subscribe(p -> log.info("The most popular tweet of user " + p.profile.name + ": " + p.tweet)); .scan((u1, u2) -> u1.author_followers > u2.author_followers ? u1 : u2)
  • 24. streamClient.getStream("RxJava", "JEEConf", "Java", "Trump") .scan((u1, u2) -> u1.author_followers > u2.author_followers ? u1 : u2) .distinctUntilChanged() .map(p -> p.author) .flatMap(name -> { Observable<Profile> profile = client.getUserProfile(name) .subscribeOn(Schedulers.io()); Observable<Tweet> tweet = client.getUserRecentTweets(name) .defaultIfEmpty(null) .reduce((t1, t2) -> t1.retweet_count > t2.retweet_count ? t1 : t2) .subscribeOn(Schedulers.io()); return Observable.zip(profile, tweet, UserWithTweet::new); }) .subscribeOn(Schedulers.io()) .observeOn(Schedulers.immediate()) .subscribe(p -> log.info("The most popular tweet of user " + p.profile.name + ": " + p.tweet));
  • 26. ▸ API is big (150+ methods to remember) ▸ Requires to understand underlying magic ▸ Hard to debug ▸ Don’t forget about back pressure Conclusions: pitfalls
  • 27. ▸ It is functional, it is reactive* ▸ Good for integration scenarios ▸ Allows to control execution threads ▸ Easy to compose workflows ▸ Easy to integrate into existing solutions ▸ Easy to test * RxJava is inspired by FRP (Functional Reactive Programming), but doesn’t implement it Conclusions: strength
  • 28.
  • 29. Q&A
  • 30. Thanks Presentation template by SlidesCarnival @siromaha aigooor@gmail.com

Editor's Notes

  1. Добрий день Звати Ігор Сьогодні за 15 ха розкажу про RxJava ТУТ ЛІНК НА ПРЕЗЕНТАШКУ
  2. Тим часом: GL Працюю з Java 7 років МЕТА: заціквити, підштовхнути до Реактивщини Ще одне: прошу НЕНАГАЛЬНІ питання запам’ятовувати, їх ми обговоримо вкінці.
  3. Спрощено виглядає сучасна апа БАГАТО: даних, клієнтів, різних API, зовнішніх сервісів як це менеджити?
  4. ДЛЯ ЦЬОГО Є КУПА РІШЕНЬ НАСПРАВДІ ЇХ БІЛЬШЕ цікавить - цей ЗВІРЬОК
  5. Хтось працював з RxJava? З іншими РЕАКТИВНИМИ системами?
  6. Ідея не нова В ТАБОРІ ВОРОГІВ з 2009 Потім був порт на JS Завдяки БЕНУ КРІСТІНСЕНУ з Netflix Є порти під інші мови
  7. Спробуємо реалізувати таке Зверху рядок слів, які нас цікавлять в твітах Зліва - потік цих твітів Справа - топ автори і їх топ твіти Трохи штучно, для демо згодиться
  8. БУДЕМО ВИКОРИСТОВУВАТИ Stream API - бібліотека від twitter 2 REST запита: профіль і недавні твіти
  9. Коротко - PUSH ільтернатива Java 8 Stream API Дуже схожі ГЛЯНЕМО потік твітів -> популярний твіт популярного автора
  10. Коротко - PUSH ільтернатива Java 8 Stream API Дуже схожі ГЛЯНЕМО потік твітів -> популярний твіт популярного автора
  11. Доменні об’єкти ТВІТ (+ деяка інфа про автора) ПРОФІЛЬ (зовсім кілька атрибутів) КОНТЕЙНЕР - тримати разом ганятимемо через Observable потоки
  12. Marble Diagrams - ВІЗУАЛІЗАЦІЯ 1. Просто потік твітів (+ автор) 2. Порівнюємо з допоки найпопюлярнішим автором і замінюємо популярнішим 3. Фільтруємо унікальні 4. Залишимо лише ім’я автора 5. По імені -> профіль + список остінніх твітів (REST API) 6. список остінніх твітів -> популярний твіт (reduce) 7. ПАРАЛЕЛЬНО 8. Зібрати дані повенути як тільки готові дочірні 9. FLATMAP -> верне результат 10. СКЛАДНО? 11. Почнем з простого - витягнемо профіль
  13. Цей код робочий)) АСИНХРОННО?
  14. ЩО ЗМІНИЛОСЬ? При виклику методу код не виконається - РЕЄСТРАЦІЯ дії
  15. 1. Обробка помилок 2. Додаткова дія коли цей потік закінчиться Note: рішення про помилку робиться в момент виклику методу! Нічого складного?
  16. Ну що, зробимо паралельно? До речі такий пістолет дійно існує: Італійська конпанія Arsenal Firearms з 2011 року робить такі іграшки При чому в кількох калібрах)))
  17. Ми бачили як дістати ПРОФІЛЬ Припустимо що так само - ТВІТИ Тре зрозуміти як зробити це паралельно
  18. Note: перший твіт, а не найпопулярніший ВИПРАВИМО
  19. Ось цю частину ми реалізували Спробує опанувати решту
  20. Для цього підпишимось на ПОТІК
  21. Нам треба: 1. Stream Client - вертає потік твітів 2. Але у нас є проблема - мало твітів! 3. Рішення просте
  22. Ось так
  23. Ось повне рішення! ПРАВДА БАГАТО - 17 рядків коду? Порівняємо з діаграмою - має бути щось схоже!
  24. Ось повне рішення! ПРАВДА БАГАТО - 17 рядків коду? Порівняємо з діаграмою - має бути щось схоже!
  25. ЩЕ РАЗ НАЗАД - ДЛЯ ПОРІВНЯННЯ ОК, підіб’ємо підсумки?
  26. RxJava - Compositional Event Systems (CES) Різниця у формальному визначенні, для нас це не важливо
  27. Думали усе? Я ж сказав що легко тестити! TestSubscriber - частина RxJava TestScheduler - для генерації певних подій СПОДІВАЮСЬ ВИ ПОБАЧИЛИ: RxJava це круто
  28. Ну от, така от RxJava за 20 хв. Готовий відповісти на питання, маємо 3-5 хв. 2-3 питання Останнє питання: у нас ще одна презентація
  29. Дякую за увагу Будуть патання - гукайте