SlideShare a Scribd company logo
1 of 38
Download to read offline
Building Scalable Stateless Applications with RxJava 
Rick Warren | Principal Engineer, eHarmony 
rwarren@eharmony.com | @DangerLemming
RxJava 
• Encapsulates data sequences: Observable 
• Provides composable operations on them 
• Abstracts away threading and synch 
• Port from Microsoft .NET Reactive Extensions 
• Java 6+, Groovy, Clojure, JRuby, Kotlin, and 
Scala; Android-compatible
Netflix 
Client Client Client Client Client 
Coarse-Grained API 
Orchestration Layer 
Mi- -cro Ser- -vic- -es
Applicability 
Application or Presentation-Layer Service 
Client Client Client Client Client 
Data 
Source 
Data 
Source 
Data 
Source 
Data 
Source 
Data 
Source
3 Problems 
1. Streaming queries 
2. Rate-limited APIs 
(with retries) 
3. Using Futures
Streaming Queries 
Data 
Store Service Client 
1 2 3 
1. Query lots of data from NoSQL store 
2. Enrich, filter, and score on the fly 
3. Deliver “best” results to client
Streaming Queries 
1 
Query 
2 
Enrich 
3 
Deliver 
+ = 
Too Much Latency
Streaming Queries 
1 
Query 
&& = 
2 
Enrich 
3 
Deliver 
More Efficient
Streaming Queries 
Iterables 
Data 
Store Client 
Read 
Enrich 
Drain 
Score 
• Iterator pattern for fast start and lower footprint 
• Composed as Decorators for flexibility 
• Limitation: Doesn’t abstract timing, concurrency
Rate-Limited APIs 
Scenario: Ingest data from 
public API—they will refuse 
rapid requests! 
YouTube, 
Facebook, 
etc. 
Your 
Service
Rate-Limited APIs 
YouTube, 
Facebook, 
etc. 
Your 
Service 
Insight: The module responsible 
for what data is available 
is also responsible 
for when data is available
Rate-Limited APIs 
YouTube, 
Facebook, 
etc. 
Your 
Service 
Solution: Facade API with 
augmented Visitors to 
encapsulate timing and retries 
interface 
DataVisitor<T> 
extends 
java.io.Closeable 
{ 
void 
accept(T 
data); 
} 
Limitation: Scheduling 
doesn't generalize
Using Futures 
javax.ws.rs.client.Invocation 
Response 
invoke() 
Future<Response> 
submit() 
• API and implementation cluttered with concurrency variants 
• Caller responsible for concurrency, but has least information 
• What can you do with a Future besides block?
Using Futures 
What about Guava’s ListenableFuture? 
ListeningExecutorService 
service 
= 
MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10)); 
ListenableFuture<Explosion> 
explosion 
= 
service.submit(new 
Callable<Explosion>() 
{ 
public 
Explosion 
call() 
{ 
return 
pushBigRedButton(); 
} 
}); 
Futures.addCallback(explosion, 
new 
FutureCallback<Explosion>() 
{ 
public 
void 
onSuccess(Explosion 
explosion) 
{ 
walkAwayFrom(explosion); 
} 
public 
void 
onFailure(Throwable 
thrown) 
{ 
battleArchNemesis(); 
} 
}); 
• Requires access to ExecutorService! 
• Still hard to compose 
• Doesn’t generalize to multiple results
Make It 
Work 
Interactions should: 
• Support multiple values 
• Be efficient & incremental 
• Encapsulate timing 
• Compose operations
RxJava: Observable 
• Like 
Iterable, 
but offers 
fluent chaining 
operations 
• Like Stream, 
but supports 
async 
termination and 
error handling
Iterable Example 
try 
{ 
for 
(E 
elem 
: 
elements) 
{ 
onNext(elem); 
} 
onCompleted(); 
} 
catch 
(Throwable 
ex) 
{ 
onError(ex); 
}
Iterable Example 
try 
{ 
elements.forEach(elem 
-­‐> 
onNext(elem) 
); 
onCompleted(); 
} 
catch 
(Throwable 
ex) 
{ 
onError(ex); 
} 
First-class 
Visitor 
(Consumer)
Stream Example 
try 
{ 
elements.parallelStream() 
Parallelize 
operations 
.filter(condition) 
.map(transformation) 
.forEach(elem 
-­‐> 
onNext(elem)); 
onCompleted(); 
} 
catch 
(Throwable 
ex) 
{ 
onError(ex); 
} 
Still serial
Observable Example 
elements 
.filter(condition) 
.map(transformation) 
.subscribe( 
elem 
-­‐> 
onNext(elem), 
ex 
-­‐> 
onError(ex), 
() 
-­‐> 
onCompleted()); 
Fully 
async’able
Creating an Observable 
import 
rx.*; 
Observable<String> 
o 
= 
Observable.just( 
"a", 
"b", 
"c"); 
Iterable<String> 
it 
= 
ImmutableList.of( 
"a", 
"b", 
"c"); 
Observable<String> 
o 
= 
Observable.from(it); 
Future<String> 
f 
= 
exec.submit(myTask); 
Observable<String> 
o 
= 
Observable.from( 
f, 
Schedulers.from(exec));
Example: JDBC 
public 
final 
class 
ObservableDB 
{ 
private 
final 
DataSource 
db; 
public 
ObservableDB(final 
DataSource 
source) 
{ 
this.db 
= 
Objects.requireNonNull(source); 
} 
/** 
Each 
emitted 
List 
represents 
a 
row 
in 
the 
ResultSet. 
*/ 
public 
Observable<List<Object>> 
select( 
final 
String 
sql, 
final 
Iterable<?> 
params) 
{ 
return 
Observable.create(new 
Observable.OnSubscribe<List<Object>>() 
{ 
@Override 
public 
void 
call(final 
Subscriber<? 
super 
List<Object>> 
sub) 
{ 
// 
... 
} 
}); 
} 
}
Example: JDBC 
@Override 
public 
void 
call(final 
Subscriber<? 
super 
List<Object>> 
sub) 
{ 
try 
{ 
try 
(Connection 
cx 
= 
db.getConnection(); 
PreparedStatement 
stmt 
= 
cx.prepareStatement(sql)) 
{ 
int 
i 
= 
0; 
for 
(final 
Object 
p 
: 
params) 
{ 
stmt.setObject(i++, 
p); 
} 
try 
(ResultSet 
results 
= 
stmt.executeQuery()) 
{ 
while 
(results.next() 
&& 
!sub.isUnsubscribed()) 
{ 
final 
Lists<Object> 
row 
= 
new 
ArrayList<>(); 
for 
(int 
col 
= 
0; 
col 
< 
results.getMetaData().getColumnCount(); 
++col) 
{ 
row.add(results.getObject(col)); 
} 
sub.onNext(row); 
} 
} 
} 
if 
(!sub.isUnsubscribed()) 
{ 
sub.onCompleted(); 
} 
} 
catch 
(final 
Exception 
ex) 
{ 
if 
(!sub.isUnsubscribed()) 
{ 
sub.onError(ex); 
} 
} 
} 
Serialize 
Call n times 
Call one or 
the other, 
once
Example: JDBC 
public 
void 
printProductCatalog( 
final 
DataSource 
source, 
final 
boolean 
awesome) 
{ 
ObservableDB 
db 
= 
new 
ObservableDB(source); 
Subscription 
subscription 
= 
db.select( 
"SELECT 
* 
FROM 
products 
WHERE 
isAwesome=?", 
Collections.singleton(awesome)) 
// 
Func1<List<Object>, 
Product> 
: 
.map(unmarshallRowIntoProduct()) 
// 
Func1<Product, 
Observable<ProductWithPrice>> 
: 
.flatMap(remoteLookupPriceForProduct(this.priceService)) 
.take(NUM_PAGES 
* 
NUM_PRODUCTS_PER_PAGE) 
.window(NUM_PAGES) 
.subscribe(new 
Observer<Observable<ProductWithPrice>>() 
{ 
... 
}); 
// 
Some 
time 
later, 
if 
we 
change 
our 
minds: 
//subscription.unsubscribe(); 
} 
interface 
PriceService 
{ 
Observable<ProductWithPrice> 
getPrice(Product 
p); 
}
Example: JDBC 
.subscribe(new 
Observer<Observable<ProductWithPrice>>() 
{ 
private 
final 
AtomicInteger 
pageNumber 
= 
new 
AtomicInteger(1); 
@Override 
public 
void 
onNext(final 
Observable<ProductWithPrice> 
page) 
{ 
System.out.println("Page 
" 
+ 
pageNumber.getAndIncrement()); 
page.forEach(new 
Action1<ProductWithPrice>() 
{ 
@Override 
public 
void 
call(final 
ProductWithPrice 
product) 
{ 
System.out.println("Product:" 
+ 
product); 
} 
}); 
} 
@Override 
public 
void 
onError(final 
Throwable 
ex) 
{ 
System.err.println("This 
is 
how 
you 
handle 
errors? 
Srsly?"); 
} 
@Override 
public 
void 
onCompleted() 
{ 
System.out.println("Copyright 
2014 
ACME 
Catalog 
Company"); 
} 
});
Operations Useful stuff, built in
Content Filtering 
• Observable<T> 
filter(Func1<T, 
Boolean> 
predicate) 
• Observable<T> 
skip(int 
num) 
• Observable<T> 
take(int 
num) 
• Observable<T> 
takeLast(int 
num) 
• Observable<T> 
elementAt(int 
index) 
• Observable<T> 
distinct() 
• Observable<T> 
distinctUntilChanged()
Time Filtering 
• Observable<T> 
throttleFirst(long 
duration, 
TimeUnit 
unit) 
• Observable<T> 
throttleLast(long 
duration, 
TimeUnit 
unit) 
• Observable<T> 
timeout(long 
duration, 
TimeUnit 
unit)
Transformation 
• Observable<R> 
map(Func1<T, 
R> 
func) 
• Observable<R> 
flatMap(Func1<T, 
Observable<R>> 
func) 
• Observable<R> 
cast(Class<R> 
klass) 
• Observable<GroupedObservable<K, 
T>> 
groupBy(Func1<T, 
K> 
keySelector)
Concurrency Encapsulated, so usually you don’t care
Concurrency 
1. Single-threaded and synchronous by default: 
RxJava doesn’t magically create new threads for you 
2. When creating an Observable, invoke Subscriber 
from any thread you like (or use Actors, etc.) 
3. Derive new Observables by binding subscription 
and/or observation to Schedulers
Rescheduling 
Observable<T> 
rescheduled 
= 
obs 
.subscribeOn(mySubScheduler) 
.observeOn(myObsScheduler);
What’s a Scheduler? 
Policy for time-sharing among Workers 
• Worker: Serial collection of scheduled Actions 
• Action: Callable unit of work, e.g. Observable’s 
subscription or notification
Built-in Schedulers 
• Immediate—Schedulers.immediate() 
• Run without scheduling in calling thread 
• Trampoline—Schedulers.trampoline() 
• Enqueue Actions in thread-local priority queue 
• Computation—Schedulers.computation() 
• Enqueue in event loop with as many threads as cores
Built-in Schedulers 
• New Thread—Schedulers.newThread() 
• Each Worker is a single-thread ExecutorService 
• I/O—Schedulers.io() 
• Mostly like New Thread, but with some pooling 
• Executor Service—Schedulers.from( 
ExecutorService) 
• Bind new Scheduler to arbitrary ExecutorService, with 
external serialization of Actions. Observations may hop 
threads!
Bring Data to Calling Thread 
Avoid whenever possible 
myObservable.toBlocking() 
Operations: 
• first() 
• last() 
• toFuture() 
• toIterable()
Learn More: 
• Wiki: https://github.com/ReactiveX/RxJava/wiki 
• JavaDoc: http://reactivex.io/RxJava/javadoc/
More Resources 
• Netflix API architecture: http:// 
techblog.netflix.com/2013/01/ 
optimizing-netflix-api.html 
• Jersey: https://jersey.java.net/ 
apidocs/latest/jersey/index.html 
• Guava ListenableFuture: 
https://code.google.com/p/ 
guava-libraries/wiki/ 
ListenableFutureExplained 
• rxjava-jdbc: https://github.com/ 
davidmoten/rxjava-jdbc/ 
• Email: 
rwarren@eharmony.com 
• Twitter: 
@DangerLemming 
• GitHub: https:// 
github.com/rickbw 
• LinkedIn: https:// 
www.linkedin.com/in/ 
rickbwarren

More Related Content

What's hot

Reactive programming using rx java & akka actors - pdx-scala - june 2014
Reactive programming   using rx java & akka actors - pdx-scala - june 2014Reactive programming   using rx java & akka actors - pdx-scala - june 2014
Reactive programming using rx java & akka actors - pdx-scala - june 2014
Thomas Lockney
 

What's hot (20)

An Introduction to RxJava
An Introduction to RxJavaAn Introduction to RxJava
An Introduction to RxJava
 
Introduction to rx java for android
Introduction to rx java for androidIntroduction to rx java for android
Introduction to rx java for 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
 
RxJava on Android
RxJava on AndroidRxJava on Android
RxJava on Android
 
Reactive Fault Tolerant Programming with Hystrix and RxJava
Reactive Fault Tolerant Programming with Hystrix and RxJavaReactive Fault Tolerant Programming with Hystrix and RxJava
Reactive Fault Tolerant Programming with Hystrix and RxJava
 
Reactive programming with examples
Reactive programming with examplesReactive programming with examples
Reactive programming with examples
 
Reactive programming with Rxjava
Reactive programming with RxjavaReactive programming with Rxjava
Reactive programming with Rxjava
 
RxJava applied [JavaDay Kyiv 2016]
RxJava applied [JavaDay Kyiv 2016]RxJava applied [JavaDay Kyiv 2016]
RxJava applied [JavaDay Kyiv 2016]
 
RxJava 2.0 介紹
RxJava 2.0 介紹RxJava 2.0 介紹
RxJava 2.0 介紹
 
Rxjava 介紹與 Android 中的 RxJava
Rxjava 介紹與 Android 中的 RxJavaRxjava 介紹與 Android 中的 RxJava
Rxjava 介紹與 Android 中的 RxJava
 
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 Retrofit and RxJava
Introduction to Retrofit and RxJavaIntroduction to Retrofit and RxJava
Introduction to Retrofit and RxJava
 
RxJava - introduction & design
RxJava - introduction & designRxJava - introduction & design
RxJava - introduction & design
 
Practical RxJava for Android
Practical RxJava for AndroidPractical RxJava for Android
Practical RxJava for Android
 
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 using rx java & akka actors - pdx-scala - june 2014
Reactive programming   using rx java & akka actors - pdx-scala - june 2014Reactive programming   using rx java & akka actors - pdx-scala - june 2014
Reactive programming using rx java & akka actors - pdx-scala - june 2014
 
Reactive Thinking in Java
Reactive Thinking in JavaReactive Thinking in Java
Reactive Thinking in Java
 
Javantura v3 - Going Reactive with RxJava – Hrvoje Crnjak
Javantura v3 - Going Reactive with RxJava – Hrvoje CrnjakJavantura v3 - Going Reactive with RxJava – Hrvoje Crnjak
Javantura v3 - Going Reactive with RxJava – Hrvoje Crnjak
 
RxJava from the trenches
RxJava from the trenchesRxJava from the trenches
RxJava from the trenches
 

Similar to Building Scalable Stateless Applications with RxJava

Similar to Building Scalable Stateless Applications with RxJava (20)

Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on Android
 
What is new in java 8 concurrency
What is new in java 8 concurrencyWhat is new in java 8 concurrency
What is new in java 8 concurrency
 
RxJava2 Slides
RxJava2 SlidesRxJava2 Slides
RxJava2 Slides
 
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...
 
Intro to Reactive Thinking and RxJava 2
Intro to Reactive Thinking and RxJava 2Intro to Reactive Thinking and RxJava 2
Intro to Reactive Thinking and RxJava 2
 
The Mayans Lost Guide to RxJava on Android
The Mayans Lost Guide to RxJava on AndroidThe Mayans Lost Guide to RxJava on Android
The Mayans Lost Guide to RxJava on Android
 
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
 
Functional UIs with Java 8 and Vaadin JavaOne2014
Functional UIs with Java 8 and Vaadin JavaOne2014Functional UIs with Java 8 and Vaadin JavaOne2014
Functional UIs with Java 8 and Vaadin JavaOne2014
 
Belfast JUG 23-10-2013
Belfast JUG 23-10-2013Belfast JUG 23-10-2013
Belfast JUG 23-10-2013
 
Iniciación rx java
Iniciación rx javaIniciación rx java
Iniciación rx java
 
Modern Android app library stack
Modern Android app library stackModern Android app library stack
Modern Android app library stack
 
Top 10 RxJs Operators in Angular
Top 10 RxJs Operators in Angular Top 10 RxJs Operators in Angular
Top 10 RxJs Operators in Angular
 
How to perform debounce in react
How to perform debounce in reactHow to perform debounce in react
How to perform debounce in react
 
Reactive programming with RxAndroid
Reactive programming with RxAndroidReactive programming with RxAndroid
Reactive programming with RxAndroid
 
Rxandroid
RxandroidRxandroid
Rxandroid
 
RxAndroid
RxAndroidRxAndroid
RxAndroid
 
OSGi ecosystems compared on Apache Karaf - Christian Schneider
OSGi ecosystems compared on Apache Karaf - Christian SchneiderOSGi ecosystems compared on Apache Karaf - Christian Schneider
OSGi ecosystems compared on Apache Karaf - Christian Schneider
 
Finagle and Java Service Framework at Pinterest
Finagle and Java Service Framework at PinterestFinagle and Java Service Framework at Pinterest
Finagle and Java Service Framework at Pinterest
 
RxJava@Android
RxJava@AndroidRxJava@Android
RxJava@Android
 
Saving lives with rx java
Saving lives with rx javaSaving lives with rx java
Saving lives with rx java
 

More from Rick Warren

More from Rick Warren (20)

Real-World Git
Real-World GitReal-World Git
Real-World Git
 
Letters from the Trenches: Lessons Learned Taking MongoDB to Production
Letters from the Trenches: Lessons Learned Taking MongoDB to ProductionLetters from the Trenches: Lessons Learned Taking MongoDB to Production
Letters from the Trenches: Lessons Learned Taking MongoDB to Production
 
Patterns of Data Distribution
Patterns of Data DistributionPatterns of Data Distribution
Patterns of Data Distribution
 
Data-centric Invocable Services
Data-centric Invocable ServicesData-centric Invocable Services
Data-centric Invocable Services
 
Engineering Interoperable and Reliable Systems
Engineering Interoperable and Reliable SystemsEngineering Interoperable and Reliable Systems
Engineering Interoperable and Reliable Systems
 
Scaling DDS to Millions of Computers and Devices
Scaling DDS to Millions of Computers and DevicesScaling DDS to Millions of Computers and Devices
Scaling DDS to Millions of Computers and Devices
 
DDS in a Nutshell
DDS in a NutshellDDS in a Nutshell
DDS in a Nutshell
 
Java 5 Language PSM for DDS: Final Submission
Java 5 Language PSM for DDS: Final SubmissionJava 5 Language PSM for DDS: Final Submission
Java 5 Language PSM for DDS: Final Submission
 
Java 5 PSM for DDS: Revised Submission (out of date)
Java 5 PSM for DDS: Revised Submission (out of date)Java 5 PSM for DDS: Revised Submission (out of date)
Java 5 PSM for DDS: Revised Submission (out of date)
 
C++ PSM for DDS: Revised Submission
C++ PSM for DDS: Revised SubmissionC++ PSM for DDS: Revised Submission
C++ PSM for DDS: Revised Submission
 
Web-Enabled DDS: Revised Submission
Web-Enabled DDS: Revised SubmissionWeb-Enabled DDS: Revised Submission
Web-Enabled DDS: Revised Submission
 
Java 5 PSM for DDS: Initial Submission (out of date)
Java 5 PSM for DDS: Initial Submission (out of date)Java 5 PSM for DDS: Initial Submission (out of date)
Java 5 PSM for DDS: Initial Submission (out of date)
 
Extensible and Dynamic Topic Types for DDS, Beta 1
Extensible and Dynamic Topic Types for DDS, Beta 1Extensible and Dynamic Topic Types for DDS, Beta 1
Extensible and Dynamic Topic Types for DDS, Beta 1
 
Mapping the RESTful Programming Model to the DDS Data-Centric Model
Mapping the RESTful Programming Model to the DDS Data-Centric ModelMapping the RESTful Programming Model to the DDS Data-Centric Model
Mapping the RESTful Programming Model to the DDS Data-Centric Model
 
Large-Scale System Integration with DDS for SCADA, C2, and Finance
Large-Scale System Integration with DDS for SCADA, C2, and FinanceLarge-Scale System Integration with DDS for SCADA, C2, and Finance
Large-Scale System Integration with DDS for SCADA, C2, and Finance
 
Data-Centric and Message-Centric System Architecture
Data-Centric and Message-Centric System ArchitectureData-Centric and Message-Centric System Architecture
Data-Centric and Message-Centric System Architecture
 
Extensible and Dynamic Topic Types for DDS
Extensible and Dynamic Topic Types for DDSExtensible and Dynamic Topic Types for DDS
Extensible and Dynamic Topic Types for DDS
 
Easing Integration of Large-Scale Real-Time Systems with DDS
Easing Integration of Large-Scale Real-Time Systems with DDSEasing Integration of Large-Scale Real-Time Systems with DDS
Easing Integration of Large-Scale Real-Time Systems with DDS
 
Java 5 API for DDS RFP (out of date)
Java 5 API for DDS RFP (out of date)Java 5 API for DDS RFP (out of date)
Java 5 API for DDS RFP (out of date)
 
Introduction to DDS
Introduction to DDSIntroduction to DDS
Introduction to DDS
 

Recently uploaded

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
 
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
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
masabamasaba
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 
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
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
masabamasaba
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
VictorSzoltysek
 

Recently uploaded (20)

MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Harare%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Harare
 
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
 
%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
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
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...
 
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...
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
 
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?
 
%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
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
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the past
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
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...
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
%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
 

Building Scalable Stateless Applications with RxJava

  • 1. Building Scalable Stateless Applications with RxJava Rick Warren | Principal Engineer, eHarmony rwarren@eharmony.com | @DangerLemming
  • 2. RxJava • Encapsulates data sequences: Observable • Provides composable operations on them • Abstracts away threading and synch • Port from Microsoft .NET Reactive Extensions • Java 6+, Groovy, Clojure, JRuby, Kotlin, and Scala; Android-compatible
  • 3. Netflix Client Client Client Client Client Coarse-Grained API Orchestration Layer Mi- -cro Ser- -vic- -es
  • 4. Applicability Application or Presentation-Layer Service Client Client Client Client Client Data Source Data Source Data Source Data Source Data Source
  • 5. 3 Problems 1. Streaming queries 2. Rate-limited APIs (with retries) 3. Using Futures
  • 6. Streaming Queries Data Store Service Client 1 2 3 1. Query lots of data from NoSQL store 2. Enrich, filter, and score on the fly 3. Deliver “best” results to client
  • 7. Streaming Queries 1 Query 2 Enrich 3 Deliver + = Too Much Latency
  • 8. Streaming Queries 1 Query && = 2 Enrich 3 Deliver More Efficient
  • 9. Streaming Queries Iterables Data Store Client Read Enrich Drain Score • Iterator pattern for fast start and lower footprint • Composed as Decorators for flexibility • Limitation: Doesn’t abstract timing, concurrency
  • 10. Rate-Limited APIs Scenario: Ingest data from public API—they will refuse rapid requests! YouTube, Facebook, etc. Your Service
  • 11. Rate-Limited APIs YouTube, Facebook, etc. Your Service Insight: The module responsible for what data is available is also responsible for when data is available
  • 12. Rate-Limited APIs YouTube, Facebook, etc. Your Service Solution: Facade API with augmented Visitors to encapsulate timing and retries interface DataVisitor<T> extends java.io.Closeable { void accept(T data); } Limitation: Scheduling doesn't generalize
  • 13. Using Futures javax.ws.rs.client.Invocation Response invoke() Future<Response> submit() • API and implementation cluttered with concurrency variants • Caller responsible for concurrency, but has least information • What can you do with a Future besides block?
  • 14. Using Futures What about Guava’s ListenableFuture? ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10)); ListenableFuture<Explosion> explosion = service.submit(new Callable<Explosion>() { public Explosion call() { return pushBigRedButton(); } }); Futures.addCallback(explosion, new FutureCallback<Explosion>() { public void onSuccess(Explosion explosion) { walkAwayFrom(explosion); } public void onFailure(Throwable thrown) { battleArchNemesis(); } }); • Requires access to ExecutorService! • Still hard to compose • Doesn’t generalize to multiple results
  • 15. Make It Work Interactions should: • Support multiple values • Be efficient & incremental • Encapsulate timing • Compose operations
  • 16. RxJava: Observable • Like Iterable, but offers fluent chaining operations • Like Stream, but supports async termination and error handling
  • 17. Iterable Example try { for (E elem : elements) { onNext(elem); } onCompleted(); } catch (Throwable ex) { onError(ex); }
  • 18. Iterable Example try { elements.forEach(elem -­‐> onNext(elem) ); onCompleted(); } catch (Throwable ex) { onError(ex); } First-class Visitor (Consumer)
  • 19. Stream Example try { elements.parallelStream() Parallelize operations .filter(condition) .map(transformation) .forEach(elem -­‐> onNext(elem)); onCompleted(); } catch (Throwable ex) { onError(ex); } Still serial
  • 20. Observable Example elements .filter(condition) .map(transformation) .subscribe( elem -­‐> onNext(elem), ex -­‐> onError(ex), () -­‐> onCompleted()); Fully async’able
  • 21. Creating an Observable import rx.*; Observable<String> o = Observable.just( "a", "b", "c"); Iterable<String> it = ImmutableList.of( "a", "b", "c"); Observable<String> o = Observable.from(it); Future<String> f = exec.submit(myTask); Observable<String> o = Observable.from( f, Schedulers.from(exec));
  • 22. Example: JDBC public final class ObservableDB { private final DataSource db; public ObservableDB(final DataSource source) { this.db = Objects.requireNonNull(source); } /** Each emitted List represents a row in the ResultSet. */ public Observable<List<Object>> select( final String sql, final Iterable<?> params) { return Observable.create(new Observable.OnSubscribe<List<Object>>() { @Override public void call(final Subscriber<? super List<Object>> sub) { // ... } }); } }
  • 23. Example: JDBC @Override public void call(final Subscriber<? super List<Object>> sub) { try { try (Connection cx = db.getConnection(); PreparedStatement stmt = cx.prepareStatement(sql)) { int i = 0; for (final Object p : params) { stmt.setObject(i++, p); } try (ResultSet results = stmt.executeQuery()) { while (results.next() && !sub.isUnsubscribed()) { final Lists<Object> row = new ArrayList<>(); for (int col = 0; col < results.getMetaData().getColumnCount(); ++col) { row.add(results.getObject(col)); } sub.onNext(row); } } } if (!sub.isUnsubscribed()) { sub.onCompleted(); } } catch (final Exception ex) { if (!sub.isUnsubscribed()) { sub.onError(ex); } } } Serialize Call n times Call one or the other, once
  • 24. Example: JDBC public void printProductCatalog( final DataSource source, final boolean awesome) { ObservableDB db = new ObservableDB(source); Subscription subscription = db.select( "SELECT * FROM products WHERE isAwesome=?", Collections.singleton(awesome)) // Func1<List<Object>, Product> : .map(unmarshallRowIntoProduct()) // Func1<Product, Observable<ProductWithPrice>> : .flatMap(remoteLookupPriceForProduct(this.priceService)) .take(NUM_PAGES * NUM_PRODUCTS_PER_PAGE) .window(NUM_PAGES) .subscribe(new Observer<Observable<ProductWithPrice>>() { ... }); // Some time later, if we change our minds: //subscription.unsubscribe(); } interface PriceService { Observable<ProductWithPrice> getPrice(Product p); }
  • 25. Example: JDBC .subscribe(new Observer<Observable<ProductWithPrice>>() { private final AtomicInteger pageNumber = new AtomicInteger(1); @Override public void onNext(final Observable<ProductWithPrice> page) { System.out.println("Page " + pageNumber.getAndIncrement()); page.forEach(new Action1<ProductWithPrice>() { @Override public void call(final ProductWithPrice product) { System.out.println("Product:" + product); } }); } @Override public void onError(final Throwable ex) { System.err.println("This is how you handle errors? Srsly?"); } @Override public void onCompleted() { System.out.println("Copyright 2014 ACME Catalog Company"); } });
  • 27. Content Filtering • Observable<T> filter(Func1<T, Boolean> predicate) • Observable<T> skip(int num) • Observable<T> take(int num) • Observable<T> takeLast(int num) • Observable<T> elementAt(int index) • Observable<T> distinct() • Observable<T> distinctUntilChanged()
  • 28. Time Filtering • Observable<T> throttleFirst(long duration, TimeUnit unit) • Observable<T> throttleLast(long duration, TimeUnit unit) • Observable<T> timeout(long duration, TimeUnit unit)
  • 29. Transformation • Observable<R> map(Func1<T, R> func) • Observable<R> flatMap(Func1<T, Observable<R>> func) • Observable<R> cast(Class<R> klass) • Observable<GroupedObservable<K, T>> groupBy(Func1<T, K> keySelector)
  • 30. Concurrency Encapsulated, so usually you don’t care
  • 31. Concurrency 1. Single-threaded and synchronous by default: RxJava doesn’t magically create new threads for you 2. When creating an Observable, invoke Subscriber from any thread you like (or use Actors, etc.) 3. Derive new Observables by binding subscription and/or observation to Schedulers
  • 32. Rescheduling Observable<T> rescheduled = obs .subscribeOn(mySubScheduler) .observeOn(myObsScheduler);
  • 33. What’s a Scheduler? Policy for time-sharing among Workers • Worker: Serial collection of scheduled Actions • Action: Callable unit of work, e.g. Observable’s subscription or notification
  • 34. Built-in Schedulers • Immediate—Schedulers.immediate() • Run without scheduling in calling thread • Trampoline—Schedulers.trampoline() • Enqueue Actions in thread-local priority queue • Computation—Schedulers.computation() • Enqueue in event loop with as many threads as cores
  • 35. Built-in Schedulers • New Thread—Schedulers.newThread() • Each Worker is a single-thread ExecutorService • I/O—Schedulers.io() • Mostly like New Thread, but with some pooling • Executor Service—Schedulers.from( ExecutorService) • Bind new Scheduler to arbitrary ExecutorService, with external serialization of Actions. Observations may hop threads!
  • 36. Bring Data to Calling Thread Avoid whenever possible myObservable.toBlocking() Operations: • first() • last() • toFuture() • toIterable()
  • 37. Learn More: • Wiki: https://github.com/ReactiveX/RxJava/wiki • JavaDoc: http://reactivex.io/RxJava/javadoc/
  • 38. More Resources • Netflix API architecture: http:// techblog.netflix.com/2013/01/ optimizing-netflix-api.html • Jersey: https://jersey.java.net/ apidocs/latest/jersey/index.html • Guava ListenableFuture: https://code.google.com/p/ guava-libraries/wiki/ ListenableFutureExplained • rxjava-jdbc: https://github.com/ davidmoten/rxjava-jdbc/ • Email: rwarren@eharmony.com • Twitter: @DangerLemming • GitHub: https:// github.com/rickbw • LinkedIn: https:// www.linkedin.com/in/ rickbwarren