Introductory RxJava
Introductory RxJava
Introductory RxJava
Introductory RxJava
Introductory RxJava
Introductory RxJava
Introductory RxJava
Introductory RxJava
Introductory RxJava
Introductory RxJava




Introductory RxJava








Introductory RxJava




















Introductory RxJava
Introductory RxJava
Introductory RxJava
Introductory RxJava
Introductory RxJava


















Introductory RxJava
Introductory RxJava


















Introductory RxJava
Introductory RxJava
Introductory RxJava
Introductory RxJava
Introductory RxJava
Introductory RxJava
Introductory RxJava
Introductory RxJava
Introductory RxJava
Introductory RxJava
void task(int num) {
log("begin task " + num);
sleep(1000L); // Work 1, 2,... N
log("end task " + num);
}
...
log("START");
task(1);
log("END");
log("DONE");
work 1 | work 2 | … | work N
Introductory RxJava
void task(int num) {
log("begin task " + num);
sleep(1000L); // Work 1, 2,... N
log("end task " + num);
}
...
log("START");
task(1);
task(2);
task(3);
log("END");
log("DONE");
work 1 | work 2 | … | work N work 1 | work 2 | … | work N work 1 | work 2 | … | work N
Introductory RxJava
class Task implements Runnable {
private final int id;
Task(int id) {
this.id = id;
}
public void run() {
task(id);
}
}
Introductory RxJava
void task(int num) {
log("begin task " + num);
sleep(1000L); // Work 1, 2,... N
log("end task " + num);
}
...
log(“START");
Thread t1, t2, t3;
t1 = new Thread(new Task(1)); t1.start();
t2 = new Thread(new Task(2)); t2.start();
t3 = new Thread(new Task(3)); t3.start();
log("END");
t1.join(); t2.join(); t3.join();
log("DONE");
work 1 | work 2 | … | work N
work 1 | work 2 | … | work N
work 1 | work 2 | … | work N
Introductory RxJava
synchronized void task(int num) {
log("begin task " + num);
sleep(1000L); // Work 1, 2,... N
log("end task " + num);
}
...
log("START");
Thread t1, t2, t3;
t1 = new Thread(new Task(1)); t1.start();
t2 = new Thread(new Task(2)); t2.start();
t3 = new Thread(new Task(3)); t3.start();
log("END");
t1.join(); t2.join(); t3.join();
log("DONE");
work 1 | work 2 | … | work N
work 1 | work 2 | … | work N
work 1 | work 2 | … | work N
Introductory RxJava
Introductory RxJava
Introductory RxJava
𝛥
Introductory RxJava
Introductory RxJava
Independent Each Other
Resource Consuming, Heavyweight Task
Order doesn’t Matter (Commutative)
Lightweight Calculation
Independent work part (fork) collecting result part (join)
Introductory RxJava
int total = 0;
int integral(String sector, int from, int to) {
log("Sector %s integral from %d" , sector, from);
sleep((to - from) * 1000L); // integral takes very long time
log("Sector %s integral to %d" , sector, to);
return (to - from) * 1000;
}
synchronized void accumulate(String sector, int partial) {
log("Prepare adding sector %s + %d", sector, partial);
sleep(500L); // accumulation also tasks time
total += partial;
log("Done adding sector %s + %d", sector, partial);
}
class Partial implements Runnable {
final String sector; final int from, to;
Partial(String s, int f, int t) { sector = s; from = f; to = t; }
public void run() {
int partial = integral(sector, from, to);
accumulate(sector, partial);
}
}
Introductory RxJava
t1 = new Thread(new Partial("A",0,5));
t2 = new Thread(new Partial("B",5,10));
t3 = new Thread(new Partial("C",10,15));
t1.start();
t2.start();
t3.start();
t1.join();
t2.join();
t3.join();
log("RESULT: " + total);
Introductory RxJava
Introductory RxJava
total = integral("ABC", 0, 15);
log("RESULT: " + total);
Introductory RxJava
Introductory RxJava
Introductory RxJava
Introductory RxJava
Thread Spawning Cost User Implemented Work
Introductory RxJava
⨉
⨉
Introductory RxJava
Introductory RxJava
Introductory RxJava
✈
✈
Introductory RxJava
Introductory RxJava
✈
🐌
🐌
🐌
...
Introductory RxJava
Introductory RxJava
Thread Resource User Work
Thread Resource User Work
⨉
⨉
⨉
Introductory RxJava
Introductory RxJava
Introductory RxJava
Introductory RxJava
Introductory RxJava
Introductory RxJava
Introductory RxJava
Introductory RxJava
Introductory RxJava
Introductory RxJava
Introductory RxJava
Introductory RxJava
Introductory RxJava
Introductory RxJava
Introductory RxJava
Introductory RxJava
Introductory RxJava
Introductory RxJava
List<String> list = Arrays.asList("a", "b", "c");
// list is container for “string event”,
// so “x” is string by type inference
list.forEach(x -> log(x.toUpperCase());
List<Integer> list = Arrays.asList(1, 2, 3);
// list is container for “integer event”,
// so “x” is integer by type inference
list.forEach(x -> log(x + x));
Introductory RxJava
Introductory RxJava
Introductory RxJava
Introductory RxJava
Introductory RxJava
Introductory RxJava
http://reactivex.io/intro.html
Introductory RxJava
Introductory RxJava






Introductory RxJava
Introductory RxJava
log("START");
try {
List<Integer> l = // [1, 2, 3, null, 5]
for (Integer each : l) {
log("> just: " + each);
if (!filter(each)) { continue; }
log("> filter: " + each);
Integer y = map(each);
log("> map: " + y);
log("subscribe: " + y);
}
log("completed");
} catch (Throwable t) {
log("error: " + t);
} finally {
log("END");
}
boolean filter(Integer x) {
return x % 2 == 1;
}
Integer map(Integer in) {
return in * 10;
}
log("START");
Observable.just(1, 2, 3, null, 5)
.doOnNext(x -> log("> just: " + x))
.filter(x -> x % 2 == 1)
.doOnNext(x -> log("> filter: " + x))
.map(x -> x * 10)
.doOnNext(x -> log("> map: " + x))
.subscribe(
x -> log("subscribe: " + x),
ex -> log("error: " + ex),
() -> log("completed")
);
log("END");
11.119 [main] START
11.121 [main] > just: 1
11.124 [main] > filter: 1
11.125 [main] > map: 10
11.127 [main] subscribe: 10
11.128 [main] > just: 2
11.129 [main] > just: 3
11.129 [main] > filter: 3
11.130 [main] > map: 30
11.130 [main] subscribe: 30
11.131 [main] > just: null
11.140 [main] error: java.lang.NullPointerException
11.142 [main] END
Introductory RxJava
// List<Event> events = …
try {
for (Event e : events) {
onNextEvent(e);
}
onSuccessfulComplete();
} catch (Throwable t) {
onErrorEvent(t);
}
// List<Event> events = …
try {
events.forEach(e -> onNextEvent(e));
onSuccessfulComplete();
} catch (Throwable t) {
onErrorEvent(t);
}
// Stream<Event> stream = …
try {
stream
.map(e -> transform(e))
// more transformations

.forEach(e -> onNextEvent(e));
onSuccessfulComplete();
} catch (Throwable t) {
onErrorEvent(t);
}
// Observable<Event> observable = …
observable
.map(e -> transform(e))
// more transformations

.subscribe(
e -> onNextEvent(e),
t -> onSuccessfulComplete(),
() -> onErrorEvent(t)
);
Introductory RxJava
Introductory RxJava
// input expressed as: ‘a’, ‘b’, ‘c’
Output hardWork(Input in) {
log("Beginning Work: " + in.id());
// Very HARD WORK such as Network I/O
log("Done Work: " + in.id());
return out;
}
log("start")
observable.map(x -> hardWork(x))
.filter(x -> f(x))
.operator(x -> g(x))
...
.subscribe(x -> log("result: " + x);
log("end");
Introductory RxJava
Introductory RxJava
log("start")
observable.map(x -> hardWork(x))
.filter(x -> f(x))
.operator(x -> g(x))
.subscribeOn(scheduler)
...
.subscribe(x -> log("result: " + x);
log("end");
Introductory RxJava
Introductory RxJava
log("start")
observable
.flatMap(x ->
Observable.fromCallable(() -> hardWork(x))
.subscribeOn(scheduler)
)
.filter(x -> f(x))
.operator(x -> g(x))
...
.subscribe(x -> log("result: " + x);
log("end");
log("start")
observable
.flatMap(x ->
Observable.defer(() ->
Observable.just(hardWork(x))
).subscribeOn(scheduler)
)
.filter(x -> f(x))
.operator(x -> g(x))
...
.subscribe(x -> log("result: " + x);
log("end");
Introductory RxJava
Introductory RxJava
Introductory RxJava
log("prepare");
Observable<Long> a = Observable.just("bread")
.doOnNext(x -> log("substream: " + x))
.map(x -> repository.purchase(x, 1))
.subscribeOn(schedulerA());
Observable<Long> b = Observable.just("cucumber")
.doOnNext(x -> log("substream: " + x))
.map(x -> repository.purchase(x, 3))
.subscribeOn(schedulerA());
Observable<Long> c = Observable.just("beef")
.doOnNext(x -> log("substream: " + x))
.map(x -> repository.purchase(x, 5))
.subscribeOn(schedulerA());
log("start");
Observable.just(a, b, c)
.flatMap(x -> x)
.observeOn(schedulerB())
// .reduce((x, y) -> x.add(y))
.subscribe(x -> log("Q'ty: " + x));
log("end");
Introductory RxJava
Destinations
Quoting
Customers
Introductory RxJava
Introductory RxJava
Introductory RxJava
Introductory RxJava
destination.path("recommended").request().header("Rx-User", "Async").async()
.get(new InvocationCallback<List<Destination>>() {
public void completed(final List<Destination> recommended) {
final CountDownLatch innerLatch = new CountDownLatch(recommended.size());
final Map<String, Forecast> forecasts = Collections.synchronizedMap(new HashMap<>());
for (final Destination dest : recommended) {
forecast.resolveTemplate("destination", dest.getDestination()).request().async()
.get(new InvocationCallback<Forecast>() {
public void completed(final Forecast forecast) {
forecasts.put(dest.getDestination(), forecast); innerLatch.countDown();
}
public void failed(final Throwable throwable) {
errors.offer("Forecast: " + throwable.getMessage()); innerLatch.countDown();
}
});
}
try {
if (!innerLatch.await(10, TimeUnit.SECONDS))
errors.offer("Inner: Waiting for requests to complete has timed out.");
} catch (final InterruptedException e) {
errors.offer("Inner: Waiting for requests to complete has been interrupted.");
}
// Continue with processing.
}
public void failed(final Throwable throwable) { errors.offer("Recommended: " + throwable.getMessage()); }
});
Introductory RxJava
Introductory RxJava
Introductory RxJava
Observable<Destination> recommended = RxObservable.from(dest)
.path("recommended")
.request()
.header("Rx-User", "RxJava")
.rx().get(new GenericType<List<Destination>>() {})
.onErrorReturn(t -> emptyList())
.flatMap(Observable::from)
.cache();
Observable<Forecast> forecasts = recommended.flatMap(dest ->
RxObservable.from(forecast)
.resolveTemplate("destination", dest.getDestination())
.request().rx().get(Forecast.class)
.onErrorReturn(t -> new Forecast(dest.getDestination(), "N/A")
)
);
Observable<Recommendation> recommendations = Observable.zip(
recommended,
forecasts,
Recommendation::new);
Introductory RxJava
Introductory RxJava
Existing Structure (SpringCamp 2016)
user

service
40+ tables
admin

console
client
slave

(MySQL)master

(MySQL)
adjustment
C/R/U/D
update “list” order
fetch “list”
10+ RPCs
Introductory RxJava
C/R/U/D
replicator40+ tables
admin

console
composite json
master

(MySQL)
item data
adjustment
purchase data
#1
#2
Asymmetric Replication (SpringCamp 2016)
user

service
NoSQL replica

(Couchbase) client
Introductory RxJava
List<FixedDeal> fixed = fixedDealService.find(cid, bid);
FixedDealPagination pagination = FixedDealPagination.paginate(fixed, limit);
FixedDealPage currentPage = pagination.find(pageNo);
PaginationOffset offset = PaginationOffset.adjust(currentPage);
List<String> plain = plainDealService.find(cid, bid, offset);
List<String> collatedIds = PageRankCollator.collate(currentPage, plain)
return Observable.from(collatedIds)
.concatMapEager(repository::get)
.map(JsonDocument::content)
.map(stickerFilter::apply)
.map(priceFilter::apply)
.map(viewAttributeFilter::apply)
.toList()
.toBlocking()
.singleOrDefault(Json.DEAL_LIST_DEFAULT);
Introductory RxJava
Observable<FixedDeal> fixed = fixedDealService.prepare(cid, bid, pageNo, limit);
Observable<PlainDeal> plain = plainDealService.prepare(cid, bid, pageNo, limit);
return Observable.zip(fixed, plain, DealId::collate)
.flatMap(DealId::targets)
.concatMapEager(repository::get)
.map(JsonDocument::content)
.map(stickerFilter::apply)
.map(priceFilter::apply)
.map(viewAttributeFilter::apply)
.toList()
.toBlocking()
.singleOrDefault(Json.DEAL_LIST_DEFAULT);
Introductory RxJava
// 1. gather from N tables concurrently, then aggregate
// 2. insert to replica persistence
Observable<Deal> deal = Observable.just(dealNo)
.flatMap(id -> dealRepository.findDeferred(id))
.retry(3)
.onErrorReturn(throwable -> Deal.ERROR);
Observable<DealCategory> category = Observable.just(categoryNo)
.flatMap(id -> dealCategoryRepository.findDeferred(id))
.retry(3)
.onErrorReturn(throwable -> DealCategory.ERROR);
Observable<DealScore> score = Observable.just(dealNo)
.flatMap(id -> dealScoreRepository.findDeferred(id))
.onErrorReturn(throwable -> DealScore.DEFAULT);
Observable.zip(deal, category, score, DealJson::aggregate)
.observeOn(schedulerSlot.dealSourceScheduler())
.subscribe(src -> replicaService.send(src));
Introductory RxJava
Introductory RxJava
Introductory RxJava

More Related Content

PPTX
2 презентация rx java+android
PPTX
Angular2 rxjs
PPTX
JavaScript Event Loop
PDF
Programmation fonctionnelle en JavaScript
PDF
Watch out: Observables are here to stay
PDF
JavaScript Event Loop
PDF
Mozilla とブラウザゲーム
PDF
Myraytracer
2 презентация rx java+android
Angular2 rxjs
JavaScript Event Loop
Programmation fonctionnelle en JavaScript
Watch out: Observables are here to stay
JavaScript Event Loop
Mozilla とブラウザゲーム
Myraytracer

What's hot (20)

PPT
DATASTRUCTURES PPTS PREPARED BY M V BRAHMANANDA REDDY
DOC
Ds 2 cycle
PDF
6. Generics. Collections. Streams
PDF
Rデバッグあれこれ
PDF
Rのスコープとフレームと環境と
PDF
Wprowadzenie do technologi Big Data i Apache Hadoop
PDF
2 BytesC++ course_2014_c3_ function basics&parameters and overloading
KEY
関数潮流(Function Tendency)
PDF
The Ring programming language version 1.3 book - Part 50 of 88
PDF
Oop assignment 02
PPTX
Call stack, event loop and async programming
DOCX
Java Program
PDF
The Ring programming language version 1.8 book - Part 30 of 202
PPTX
Data Types and Processing in ES6
PDF
FS2 for Fun and Profit
PDF
The Ring programming language version 1.4 book - Part 18 of 30
PDF
The Ring programming language version 1.5.3 book - Part 77 of 184
DOC
BingoConsoleApp
PDF
Monitoring Your ISP Using InfluxDB Cloud and Raspberry Pi
PDF
ReactiveCocoa workshop
DATASTRUCTURES PPTS PREPARED BY M V BRAHMANANDA REDDY
Ds 2 cycle
6. Generics. Collections. Streams
Rデバッグあれこれ
Rのスコープとフレームと環境と
Wprowadzenie do technologi Big Data i Apache Hadoop
2 BytesC++ course_2014_c3_ function basics&parameters and overloading
関数潮流(Function Tendency)
The Ring programming language version 1.3 book - Part 50 of 88
Oop assignment 02
Call stack, event loop and async programming
Java Program
The Ring programming language version 1.8 book - Part 30 of 202
Data Types and Processing in ES6
FS2 for Fun and Profit
The Ring programming language version 1.4 book - Part 18 of 30
The Ring programming language version 1.5.3 book - Part 77 of 184
BingoConsoleApp
Monitoring Your ISP Using InfluxDB Cloud and Raspberry Pi
ReactiveCocoa workshop
Ad

Similar to Introductory RxJava (20)

PDF
オープンデータを使ったモバイルアプリ開発(応用編)
PDF
Think Async: Asynchronous Patterns in NodeJS
PDF
Go: It's Not Just For Google
PDF
Javascript
KEY
Blocks+gcd入門
PDF
Something about Golang
DOCX
PRACTICAL COMPUTING
PDF
Christian Gill ''Functional programming for the people''
KEY
Haskellで学ぶ関数型言語
PPTX
Academy PRO: ES2015
PDF
Hitchhiker's Guide to Functional Programming
PDF
Haskell 101
PDF
TDC2016SP - Trilha Programação Funcional
PDF
TI1220 Lecture 6: First-class Functions
PDF
FalsyValues. Dmitry Soshnikov - ECMAScript 6
PDF
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
PDF
PDF
Monadologie
DOCX
DataStructures notes
PDF
Introduction to R programming
オープンデータを使ったモバイルアプリ開発(応用編)
Think Async: Asynchronous Patterns in NodeJS
Go: It's Not Just For Google
Javascript
Blocks+gcd入門
Something about Golang
PRACTICAL COMPUTING
Christian Gill ''Functional programming for the people''
Haskellで学ぶ関数型言語
Academy PRO: ES2015
Hitchhiker's Guide to Functional Programming
Haskell 101
TDC2016SP - Trilha Programação Funcional
TI1220 Lecture 6: First-class Functions
FalsyValues. Dmitry Soshnikov - ECMAScript 6
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
Monadologie
DataStructures notes
Introduction to R programming
Ad

Recently uploaded (20)

PDF
EaseUS PDF Editor Pro 6.2.0.2 Crack with License Key 2025
PDF
AI-Powered Threat Modeling: The Future of Cybersecurity by Arun Kumar Elengov...
PPTX
WiFi Honeypot Detecscfddssdffsedfseztor.pptx
PPTX
MLforCyber_MLDataSetsandFeatures_Presentation.pptx
PDF
Multiverse AI Review 2025: Access All TOP AI Model-Versions!
PPTX
Computer Software - Technology and Livelihood Education
PPTX
GSA Content Generator Crack (2025 Latest)
PPTX
Full-Stack Developer Courses That Actually Land You Jobs
PPTX
Cybersecurity-and-Fraud-Protecting-Your-Digital-Life.pptx
PPTX
Trending Python Topics for Data Visualization in 2025
PDF
Guide to Food Delivery App Development.pdf
PPTX
Weekly report ppt - harsh dattuprasad patel.pptx
PDF
DuckDuckGo Private Browser Premium APK for Android Crack Latest 2025
PPTX
Tech Workshop Escape Room Tech Workshop
PDF
AI Guide for Business Growth - Arna Softech
PPTX
Airline CRS | Airline CRS Systems | CRS System
PDF
CCleaner 6.39.11548 Crack 2025 License Key
PPTX
Advanced SystemCare Ultimate Crack + Portable (2025)
PDF
novaPDF Pro 11.9.482 Crack + License Key [Latest 2025]
PPTX
Download Adobe Photoshop Crack 2025 Free
EaseUS PDF Editor Pro 6.2.0.2 Crack with License Key 2025
AI-Powered Threat Modeling: The Future of Cybersecurity by Arun Kumar Elengov...
WiFi Honeypot Detecscfddssdffsedfseztor.pptx
MLforCyber_MLDataSetsandFeatures_Presentation.pptx
Multiverse AI Review 2025: Access All TOP AI Model-Versions!
Computer Software - Technology and Livelihood Education
GSA Content Generator Crack (2025 Latest)
Full-Stack Developer Courses That Actually Land You Jobs
Cybersecurity-and-Fraud-Protecting-Your-Digital-Life.pptx
Trending Python Topics for Data Visualization in 2025
Guide to Food Delivery App Development.pdf
Weekly report ppt - harsh dattuprasad patel.pptx
DuckDuckGo Private Browser Premium APK for Android Crack Latest 2025
Tech Workshop Escape Room Tech Workshop
AI Guide for Business Growth - Arna Softech
Airline CRS | Airline CRS Systems | CRS System
CCleaner 6.39.11548 Crack 2025 License Key
Advanced SystemCare Ultimate Crack + Portable (2025)
novaPDF Pro 11.9.482 Crack + License Key [Latest 2025]
Download Adobe Photoshop Crack 2025 Free

Introductory RxJava

  • 35. void task(int num) { log("begin task " + num); sleep(1000L); // Work 1, 2,... N log("end task " + num); } ... log("START"); task(1); log("END"); log("DONE");
  • 36. work 1 | work 2 | … | work N
  • 38. void task(int num) { log("begin task " + num); sleep(1000L); // Work 1, 2,... N log("end task " + num); } ... log("START"); task(1); task(2); task(3); log("END"); log("DONE");
  • 39. work 1 | work 2 | … | work N work 1 | work 2 | … | work N work 1 | work 2 | … | work N
  • 41. class Task implements Runnable { private final int id; Task(int id) { this.id = id; } public void run() { task(id); } }
  • 43. void task(int num) { log("begin task " + num); sleep(1000L); // Work 1, 2,... N log("end task " + num); } ... log(“START"); Thread t1, t2, t3; t1 = new Thread(new Task(1)); t1.start(); t2 = new Thread(new Task(2)); t2.start(); t3 = new Thread(new Task(3)); t3.start(); log("END"); t1.join(); t2.join(); t3.join(); log("DONE");
  • 44. work 1 | work 2 | … | work N work 1 | work 2 | … | work N work 1 | work 2 | … | work N
  • 46. synchronized void task(int num) { log("begin task " + num); sleep(1000L); // Work 1, 2,... N log("end task " + num); } ... log("START"); Thread t1, t2, t3; t1 = new Thread(new Task(1)); t1.start(); t2 = new Thread(new Task(2)); t2.start(); t3 = new Thread(new Task(3)); t3.start(); log("END"); t1.join(); t2.join(); t3.join(); log("DONE");
  • 47. work 1 | work 2 | … | work N work 1 | work 2 | … | work N work 1 | work 2 | … | work N
  • 51. 𝛥
  • 54. Independent Each Other Resource Consuming, Heavyweight Task
  • 55. Order doesn’t Matter (Commutative) Lightweight Calculation
  • 56. Independent work part (fork) collecting result part (join)
  • 58. int total = 0; int integral(String sector, int from, int to) { log("Sector %s integral from %d" , sector, from); sleep((to - from) * 1000L); // integral takes very long time log("Sector %s integral to %d" , sector, to); return (to - from) * 1000; } synchronized void accumulate(String sector, int partial) { log("Prepare adding sector %s + %d", sector, partial); sleep(500L); // accumulation also tasks time total += partial; log("Done adding sector %s + %d", sector, partial); } class Partial implements Runnable { final String sector; final int from, to; Partial(String s, int f, int t) { sector = s; from = f; to = t; } public void run() { int partial = integral(sector, from, to); accumulate(sector, partial); } }
  • 60. t1 = new Thread(new Partial("A",0,5)); t2 = new Thread(new Partial("B",5,10)); t3 = new Thread(new Partial("C",10,15)); t1.start(); t2.start(); t3.start(); t1.join(); t2.join(); t3.join(); log("RESULT: " + total);
  • 63. total = integral("ABC", 0, 15); log("RESULT: " + total);
  • 68. Thread Spawning Cost User Implemented Work
  • 74.
  • 75.
  • 81. Thread Resource User Work Thread Resource User Work
  • 101. List<String> list = Arrays.asList("a", "b", "c"); // list is container for “string event”, // so “x” is string by type inference list.forEach(x -> log(x.toUpperCase()); List<Integer> list = Arrays.asList(1, 2, 3); // list is container for “integer event”, // so “x” is integer by type inference list.forEach(x -> log(x + x));
  • 114. log("START"); try { List<Integer> l = // [1, 2, 3, null, 5] for (Integer each : l) { log("> just: " + each); if (!filter(each)) { continue; } log("> filter: " + each); Integer y = map(each); log("> map: " + y); log("subscribe: " + y); } log("completed"); } catch (Throwable t) { log("error: " + t); } finally { log("END"); } boolean filter(Integer x) { return x % 2 == 1; } Integer map(Integer in) { return in * 10; } log("START"); Observable.just(1, 2, 3, null, 5) .doOnNext(x -> log("> just: " + x)) .filter(x -> x % 2 == 1) .doOnNext(x -> log("> filter: " + x)) .map(x -> x * 10) .doOnNext(x -> log("> map: " + x)) .subscribe( x -> log("subscribe: " + x), ex -> log("error: " + ex), () -> log("completed") ); log("END"); 11.119 [main] START 11.121 [main] > just: 1 11.124 [main] > filter: 1 11.125 [main] > map: 10 11.127 [main] subscribe: 10 11.128 [main] > just: 2 11.129 [main] > just: 3 11.129 [main] > filter: 3 11.130 [main] > map: 30 11.130 [main] subscribe: 30 11.131 [main] > just: null 11.140 [main] error: java.lang.NullPointerException 11.142 [main] END
  • 116. // List<Event> events = … try { for (Event e : events) { onNextEvent(e); } onSuccessfulComplete(); } catch (Throwable t) { onErrorEvent(t); }
  • 117. // List<Event> events = … try { events.forEach(e -> onNextEvent(e)); onSuccessfulComplete(); } catch (Throwable t) { onErrorEvent(t); }
  • 118. // Stream<Event> stream = … try { stream .map(e -> transform(e)) // more transformations
 .forEach(e -> onNextEvent(e)); onSuccessfulComplete(); } catch (Throwable t) { onErrorEvent(t); }
  • 119. // Observable<Event> observable = … observable .map(e -> transform(e)) // more transformations
 .subscribe( e -> onNextEvent(e), t -> onSuccessfulComplete(), () -> onErrorEvent(t) );
  • 122. // input expressed as: ‘a’, ‘b’, ‘c’ Output hardWork(Input in) { log("Beginning Work: " + in.id()); // Very HARD WORK such as Network I/O log("Done Work: " + in.id()); return out; }
  • 123. log("start") observable.map(x -> hardWork(x)) .filter(x -> f(x)) .operator(x -> g(x)) ... .subscribe(x -> log("result: " + x); log("end");
  • 126. log("start") observable.map(x -> hardWork(x)) .filter(x -> f(x)) .operator(x -> g(x)) .subscribeOn(scheduler) ... .subscribe(x -> log("result: " + x); log("end");
  • 129. log("start") observable .flatMap(x -> Observable.fromCallable(() -> hardWork(x)) .subscribeOn(scheduler) ) .filter(x -> f(x)) .operator(x -> g(x)) ... .subscribe(x -> log("result: " + x); log("end");
  • 130. log("start") observable .flatMap(x -> Observable.defer(() -> Observable.just(hardWork(x)) ).subscribeOn(scheduler) ) .filter(x -> f(x)) .operator(x -> g(x)) ... .subscribe(x -> log("result: " + x); log("end");
  • 134. log("prepare"); Observable<Long> a = Observable.just("bread") .doOnNext(x -> log("substream: " + x)) .map(x -> repository.purchase(x, 1)) .subscribeOn(schedulerA()); Observable<Long> b = Observable.just("cucumber") .doOnNext(x -> log("substream: " + x)) .map(x -> repository.purchase(x, 3)) .subscribeOn(schedulerA()); Observable<Long> c = Observable.just("beef") .doOnNext(x -> log("substream: " + x)) .map(x -> repository.purchase(x, 5)) .subscribeOn(schedulerA()); log("start"); Observable.just(a, b, c) .flatMap(x -> x) .observeOn(schedulerB()) // .reduce((x, y) -> x.add(y)) .subscribe(x -> log("Q'ty: " + x)); log("end");
  • 141. destination.path("recommended").request().header("Rx-User", "Async").async() .get(new InvocationCallback<List<Destination>>() { public void completed(final List<Destination> recommended) { final CountDownLatch innerLatch = new CountDownLatch(recommended.size()); final Map<String, Forecast> forecasts = Collections.synchronizedMap(new HashMap<>()); for (final Destination dest : recommended) { forecast.resolveTemplate("destination", dest.getDestination()).request().async() .get(new InvocationCallback<Forecast>() { public void completed(final Forecast forecast) { forecasts.put(dest.getDestination(), forecast); innerLatch.countDown(); } public void failed(final Throwable throwable) { errors.offer("Forecast: " + throwable.getMessage()); innerLatch.countDown(); } }); } try { if (!innerLatch.await(10, TimeUnit.SECONDS)) errors.offer("Inner: Waiting for requests to complete has timed out."); } catch (final InterruptedException e) { errors.offer("Inner: Waiting for requests to complete has been interrupted."); } // Continue with processing. } public void failed(final Throwable throwable) { errors.offer("Recommended: " + throwable.getMessage()); } });
  • 145. Observable<Destination> recommended = RxObservable.from(dest) .path("recommended") .request() .header("Rx-User", "RxJava") .rx().get(new GenericType<List<Destination>>() {}) .onErrorReturn(t -> emptyList()) .flatMap(Observable::from) .cache(); Observable<Forecast> forecasts = recommended.flatMap(dest -> RxObservable.from(forecast) .resolveTemplate("destination", dest.getDestination()) .request().rx().get(Forecast.class) .onErrorReturn(t -> new Forecast(dest.getDestination(), "N/A") ) ); Observable<Recommendation> recommendations = Observable.zip( recommended, forecasts, Recommendation::new);
  • 148. Existing Structure (SpringCamp 2016) user
 service 40+ tables admin
 console client slave
 (MySQL)master
 (MySQL) adjustment C/R/U/D update “list” order fetch “list” 10+ RPCs
  • 150. C/R/U/D replicator40+ tables admin
 console composite json master
 (MySQL) item data adjustment purchase data #1 #2 Asymmetric Replication (SpringCamp 2016) user
 service NoSQL replica
 (Couchbase) client
  • 152. List<FixedDeal> fixed = fixedDealService.find(cid, bid); FixedDealPagination pagination = FixedDealPagination.paginate(fixed, limit); FixedDealPage currentPage = pagination.find(pageNo); PaginationOffset offset = PaginationOffset.adjust(currentPage); List<String> plain = plainDealService.find(cid, bid, offset); List<String> collatedIds = PageRankCollator.collate(currentPage, plain) return Observable.from(collatedIds) .concatMapEager(repository::get) .map(JsonDocument::content) .map(stickerFilter::apply) .map(priceFilter::apply) .map(viewAttributeFilter::apply) .toList() .toBlocking() .singleOrDefault(Json.DEAL_LIST_DEFAULT);
  • 154. Observable<FixedDeal> fixed = fixedDealService.prepare(cid, bid, pageNo, limit); Observable<PlainDeal> plain = plainDealService.prepare(cid, bid, pageNo, limit); return Observable.zip(fixed, plain, DealId::collate) .flatMap(DealId::targets) .concatMapEager(repository::get) .map(JsonDocument::content) .map(stickerFilter::apply) .map(priceFilter::apply) .map(viewAttributeFilter::apply) .toList() .toBlocking() .singleOrDefault(Json.DEAL_LIST_DEFAULT);
  • 156. // 1. gather from N tables concurrently, then aggregate // 2. insert to replica persistence Observable<Deal> deal = Observable.just(dealNo) .flatMap(id -> dealRepository.findDeferred(id)) .retry(3) .onErrorReturn(throwable -> Deal.ERROR); Observable<DealCategory> category = Observable.just(categoryNo) .flatMap(id -> dealCategoryRepository.findDeferred(id)) .retry(3) .onErrorReturn(throwable -> DealCategory.ERROR); Observable<DealScore> score = Observable.just(dealNo) .flatMap(id -> dealScoreRepository.findDeferred(id)) .onErrorReturn(throwable -> DealScore.DEFAULT); Observable.zip(deal, category, score, DealJson::aggregate) .observeOn(schedulerSlot.dealSourceScheduler()) .subscribe(src -> replicaService.send(src));