SlideShare a Scribd company logo
Praveer Gupta
How to think in
RxJava
before reacting
Reactive Programming
“a programming paradigm oriented around data
flows and the propagation of change”
– Wikipedia
Reactive Programming
0
A B
1
fx = A1 + B1
C
2 3 25
• Java VM implementation of ReactiveX
• An API for asynchronous programming with
observable streams
What is Rx in RxJava?
RxJs
Rx.NET
RxScala
RxClojure RxSwift
Rx.rbRxPY
& Others
• Client Side
Applications of RxJava
Thread switching
Event handling
• Client Side
• Server Side
Applications of RxJava
Internal Processing
Service A
Service B
Service C
Request
Total Request Processing Time
Service
Boundary
Parallel
Sequential
Response
Combine
RxJava
Observable
Subscriber
observeOn
subscribeOn
fromCallable
timer
interval
map
flatMap
timestampfilter
distinctUntilChanged
just
error
onErroronNext
onCompleted
take
buffer
zip
combineLatest
concat
merge
Scheduler
io
computation
newThread
Observer Pattern
Reactive
Functional
Asynchronous
Resiliency
TestSubscriber
TestScheduler
RxJava
fromCallable
timer
interval justerror
Observable
Subscriber onErroronNext
onCompleted
Observer Pattern
Reactive
map flatMap
timestampfilter
distinctUntilChanged
take
buffer
zip
combineLatest
concatmerge
Functional
observeOnsubscribeOn
Scheduler
io computation newThread
Asynchronous
TestSubscriber
TestScheduler
Resiliency
retry timeout
onErrorResumeNext
Observable
Subscriber onErroronNext
onCompleted
Observer Pattern
Reactive
Concept
fromCallable
timer
interval justerror
Create map flatMap
timestampfilter
distinctUntilChanged
take
buffer
zip
combineLatest
concatmerge
Functional
Operate
observeOnsubscribeOn
Scheduler
io computation newThread
Asynchronous
Resiliency
retry timeout
onErrorResumeNext
TestSubscriber
TestScheduler
Concurrent
Handle
errorsTest
How to think in RxJava
How to think in RxJava
• Introduction
Introduction
• Observer & Iterator Pattern
Subscriber
(Consumer)
Observable
(Source)
2 onNext( )2 21 1onNext( )1
Source Consumersubscribe
Produces data/event
asynchronously
Consumes data/event
as they arrive
Pushes
data/event
Observer & Iterator Pattern
onCompleted()
Observable Subscriber
(Source) (Consumer)
unsubscribe
Pushes
completion event
Observer & Iterator Pattern
Complete
onError( )XX X
Observable Subscriber
(Source) (Consumer)
unsubscribe
Pushes
error event
Observer & Iterator Pattern
Error
onNext( )1
Observable Subscriber
onError( )X
onCompleted()
Pushing Streams of Data/Events
Observer & Iterator Pattern
Introduction
• Observer & Iterator Pattern
• RxJava in Action
Subscriber<Integer> subscriber = Subscribers.create(

n -> System.out.println(n),

e -> System.out.print("Error"),

() -> System.out.println("Completed")

);
Observable<Integer> observable = Observable.just(1, 2, 3);
observable.subscribe(subscriber);
Subscriber<Integer> subscriber = Subscribers.create(

n -> System.out.println(n),

e -> System.out.print("Error"),

() -> System.out.println("Completed")

);
Subscriber<Integer> subscriber = Subscribers.create(

n -> System.out.println(n),

e -> System.out.println("Error"),

() -> System.out.println("Completed")

);
Subscriber<Integer> subscriber = Subscribers.create(

n -> System.out.println(n),

e -> System.out.println("Error"),

() -> System.out.println("Completed")

);
Subscriber<Integer> subscriber = Subscribers.create(

n -> System.out.println(n),

e -> System.out.println("Error"),

() -> System.out.println("Completed")

);
Observable<Integer> observable = Observable.just(1, 2, 3);
Subscriber<Integer> subscriber = Subscribers.create(

n -> System.out.println(n),

e -> System.out.println("Error"),

() -> System.out.println("Completed")

);
Observable<Integer> observable = Observable.just(1, 2, 3);
RxJava in Action
Source
Consumer
onNext onError
onCompleted
connect
Observable.just(1, 2, 3).subscribe(

n -> System.out.println(n),

e -> System.out.println("Error"),

() -> System.out.println("Completed")

);
1
Output:
2
3
Completed
RxJava in Action
Introduction
• Observer & Iterator Pattern
• RxJava in Action
• Creating Observables
Creating Observables
• fromCallable
Observable.fromCallable(new Callable<String>() {

@Override

public String call() throws Exception {

return "result";

}

}).subscribe(
n -> System.out.println(n),
e -> System.out.println(“Error"),
() -> System.out.println("Completed")
);
fromCallable
Observable.fromCallable(new Callable<String>() {

@Override

public String call() throws Exception {

return "result";

}

}).subscribe(
n -> System.out.println(n),
e -> System.out.println(“Error"),
() -> System.out.println("Completed")
);
Observable.fromCallable(() -> "result");
.subscribe(
s -> System.out.println(s),
e -> System.out.println("Error"),
() -> System.out.println("Completed")
);
fromCallable
Output:
result
Completed
Observable.fromCallable(() -> "result");
.subscribe(
s -> System.out.println(s),
e -> System.out.println("Error"),
() -> System.out.println("Completed")
);
Creating Observables
• fromCallable
Introduction
• Observer Pattern
• RxJava in Action
• Creating Observables
How to think in RxJava
• Introduction
• Operators
Subscriber
Operators
Observable
Operator 1
Operator 2
Operator 3
functional
Operators
• Filtering
Filtering
Timeline
Events/Data
Completion
Event
Operator
Timeline
RxMarbles
Observable.interval(1, TimeUnit.SECONDS)
.take(2)

.subscribe(
n -> System.out.println(n),
e -> System.out.println("Error"),
() -> System.out.println("Completed")
);
Output:
0
1
Completed
Filtering
Observable.interval(1, TimeUnit.SECONDS)
.take(2)

.subscribe(
n -> System.out.println(n),
e -> System.out.println("Error"),
() -> System.out.println("Completed")
);
Observable.interval(1, TimeUnit.SECONDS)
.take(2)

.subscribe(
n -> System.out.println(n),
e -> System.out.println("Error"),
() -> System.out.println("Completed")
);
Operators
• Filtering
• Transforming
Transforming
Observable
Interleaved
Completion
of source
Completion
of flatMapped
Observable
Observable.just("A", "B")

.flatMap(e -> Observable.just(1, 2).map(n -> e + n))

.subscribe(

n -> System.out.println(n),

e -> System.out.println("Error"),

() -> System.out.println("Completed")

);
Output:
A1
A2
B1
B2
Completed
Transforming
Observable.just("A", "B")

.flatMap(e -> Observable.just(1, 2).map(n -> e + n))

.subscribe(

n -> System.out.println(n),

e -> System.out.println("Error"),

() -> System.out.println("Completed")

);
Observable.just("A", "B")

.flatMap(e -> Observable.just(1, 2).map(n -> e + n))

.subscribe(

n -> System.out.println(n),

e -> System.out.println("Error"),

() -> System.out.println("Completed")

);
Operators
• Filtering
• Transforming
• Combining
Combining
Emitted only
when each
source has
emitted
Observable.zip(

Observable.just("A", "B", "C"),

Observable.interval(1, TimeUnit.SECONDS),

(a, n) -> a + n

).subscribe(

n -> System.out.println(n),

e -> System.out.println("Error"),

() -> System.out.println("Completed")

);
Output:
A0
B1
C2
Completed
Combining
Observable.zip(

Observable.just("A", "B", "C"),

Observable.interval(1, TimeUnit.SECONDS),

(a, n) -> a + n

).subscribe(

n -> System.out.println(n),

e -> System.out.println("Error"),

() -> System.out.println("Completed")

);
Operators
• Filtering
• Transforming
• Combining
How to think in RxJava
• Introduction
• Operators
• Multithreading
Multithreading
• subscribeOn
• observeOn
Multithreading
Observable

.fromCallable(() -> {

printThreadNameAnd("Observable");

return 1;

})

.filter(n -> {

printThreadNameAnd("Operator 1");

return n == 1;

})

.map(n -> {

printThreadNameAnd("Operator 2");

return "A" + n;

})

.subscribe(n -> printThreadNameAnd(“Subscriber"));
printThreadNameAnd("Done subscribing");
Observable
Operator 1
Operator 2
Subscriber
Observable

.fromCallable(() -> {

printThreadNameAnd("Observable");

return 1;

})

.filter(n -> {

printThreadNameAnd("Operator 1");

return n == 1;

})

.map(n -> {

printThreadNameAnd("Operator 2");

return "A" + n;

})

.subscribe(n -> printThreadNameAnd(“Subscriber"));
printThreadNameAnd("Done subscribing");
Observable

.fromCallable(() -> {

printThreadNameAnd("Observable");

return 1;

})

.filter(n -> {

printThreadNameAnd("Operator 1");

return n == 1;

})

.map(n -> {

printThreadNameAnd("Operator 2");

return "A" + n;

})

.subscribe(n -> printThreadNameAnd(“Subscriber"));
printThreadNameAnd("Done subscribing");
Observable

.fromCallable(() -> {

printThreadNameAnd("Observable");

return 1;

})

.filter(n -> {

printThreadNameAnd("Operator 1");

return n == 1;

})

.map(n -> {

printThreadNameAnd("Operator 2");

return "A" + n;

})

.subscribe(n -> printThreadNameAnd(“Subscriber"));
printThreadNameAnd("Done subscribing");
Observable

.fromCallable(() -> {

printThreadNameAnd("Observable");

return 1;

})

.filter(n -> {

printThreadNameAnd("Operator 1");

return n == 1;

})

.map(n -> {

printThreadNameAnd("Operator 2");

return "A" + n;

})

.subscribe(n -> printThreadNameAnd(“Subscriber"));
printThreadNameAnd("Done subscribing");
Observable

.fromCallable(() -> {

printThreadNameAnd("Observable");

return 1;

})

.filter(n -> {

printThreadNameAnd("Operator 1");

return n == 1;

})

.map(n -> {

printThreadNameAnd("Operator 2");

return "A" + n;

})

.subscribe(n -> printThreadNameAnd(“Subscriber"));
printThreadNameAnd("Done subscribing");
Observable

.fromCallable(() -> {

printThreadNameAnd("Observable");

return 1;

})

.filter(n -> {

printThreadNameAnd("Operator 1");

return n == 1;

})

.map(n -> {

printThreadNameAnd("Operator 2");

return "A" + n;

})

.subscribe(n -> printThreadNameAnd(“Subscriber"));
printThreadNameAnd("Done subscribing");
Observable

.fromCallable(() -> {

printThreadNameAnd("Observable");

return 1;

})

.filter(n -> {

printThreadNameAnd("Operator 1");

return n == 1;

})

.map(n -> {

printThreadNameAnd("Operator 2");

return "A" + n;

})

.subscribe(n -> printThreadNameAnd(“Subscriber"));
printThreadNameAnd("Done subscribing");
Observable

.fromCallable(() -> {

printThreadNameAnd("Observable");

return 1;

})

.filter(n -> {

printThreadNameAnd("Operator 1");

return n == 1;

})

.map(n -> {

printThreadNameAnd("Operator 2");

return "A" + n;

})

.subscribe(n -> printThreadNameAnd(“Subscriber"));
printThreadNameAnd("Done subscribing");
Output:
main: Observable
main: Operator 1
main: Operator 2
main: Subscriber
main: Done subscribing
RxJava is
blocking by
default
Multithreading
Observable

.fromCallable(() -> {

printThreadNameAnd("Observable");

return 1;

})

.subscribeOn(Schedulers.io())

.filter(n -> {

printThreadNameAnd("Operator 1");

return n == 1;

})

.map(n -> {

printThreadNameAnd("Operator 2");

return "A" + n;

})

.subscribe(n -> printThreadNameAnd("Subscriber"));
printThreadNameAnd("Done subscribing");
Observable

.fromCallable(() -> {

printThreadNameAnd("Observable");

return 1;

})

.subscribeOn(Schedulers.io())

.filter(n -> {

printThreadNameAnd("Operator 1");

return n == 1;

})

.map(n -> {

printThreadNameAnd("Operator 2");

return "A" + n;

})

.subscribe(n -> printThreadNameAnd("Subscriber"));
printThreadNameAnd("Done subscribing");
Output:
main: Done subscribing
RxCachedThreadScheduler-1: Observable
RxCachedThreadScheduler-1: Operator 1
RxCachedThreadScheduler-1: Operator 2
RxCachedThreadScheduler-1: Subscriber
Observable

.fromCallable(() -> {

printThreadNameAnd("Observable");

return 1;

})

.subscribeOn(Schedulers.io())

.filter(n -> {

printThreadNameAnd("Operator 1");

return n == 1;

})

.map(n -> {

printThreadNameAnd("Operator 2");

return "A" + n;

})

.subscribe(n -> printThreadNameAnd("Subscriber"));
printThreadNameAnd("Done subscribing");
Observable

.fromCallable(() -> {

printThreadNameAnd("Observable");

return 1;

})

.subscribeOn(Schedulers.io())

.filter(n -> {

printThreadNameAnd("Operator 1");

return n == 1;

})

.map(n -> {

printThreadNameAnd("Operator 2");

return "A" + n;

})

.subscribe(n -> printThreadNameAnd("Subscriber"));
printThreadNameAnd("Done subscribing");
Observable

.fromCallable(() -> {

printThreadNameAnd("Observable");

return 1;

})

.subscribeOn(Schedulers.io())

.filter(n -> {

printThreadNameAnd("Operator 1");

return n == 1;

})

.map(n -> {

printThreadNameAnd("Operator 2");

return "A" + n;

})

.subscribe(n -> printThreadNameAnd("Subscriber"));
printThreadNameAnd("Done subscribing");
Observable

.fromCallable(() -> {

printThreadNameAnd("Observable");

return 1;

})

.subscribeOn(Schedulers.io())

.filter(n -> {

printThreadNameAnd("Operator 1");

return n == 1;

})

.map(n -> {

printThreadNameAnd("Operator 2");

return "A" + n;

})

.subscribe(n -> printThreadNameAnd("Subscriber"));
printThreadNameAnd("Done subscribing");
Observable

.fromCallable(() -> {

printThreadNameAnd("Observable");

return 1;

})

.subscribeOn(Schedulers.io())

.filter(n -> {

printThreadNameAnd("Operator 1");

return n == 1;

})

.map(n -> {

printThreadNameAnd("Operator 2");

return "A" + n;

})

.subscribe(n -> printThreadNameAnd("Subscriber"));
printThreadNameAnd("Done subscribing");
Observable

.fromCallable(() -> {

printThreadNameAnd("Observable");

return 1;

})

.subscribeOn(Schedulers.io())

.filter(n -> {

printThreadNameAnd("Operator 1");

return n == 1;

})

.map(n -> {

printThreadNameAnd("Operator 2");

return "A" + n;

})

.subscribe(n -> printThreadNameAnd("Subscriber"));
printThreadNameAnd("Done subscribing");
Multithreading
Observable

.fromCallable(() -> {

printThreadNameAnd("Observable");

return 1;

})

.subscribeOn(Schedulers.io())

.filter(n -> {

printThreadNameAnd("Operator 1");

return n == 1;

})
.observeOn(Schedulers.newThread())

.map(n -> {

printThreadNameAnd("Operator 2");

return "A" + n;

})

.subscribe(n -> printThreadNameAnd("Subscriber"));
printThreadNameAnd("Done subscribing");
Output:
main: Done subscribing
RxCachedThreadScheduler-1: Observable
RxCachedThreadScheduler-1: Operator 1
RxNewThreadScheduler-1: Operator 2
RxNewThreadScheduler-1: Subscriber
Observable

.fromCallable(() -> {

printThreadNameAnd("Observable");

return 1;

})

.subscribeOn(Schedulers.io())

.filter(n -> {

printThreadNameAnd("Operator 1");

return n == 1;

})
.observeOn(Schedulers.newThread())

.map(n -> {

printThreadNameAnd("Operator 2");

return "A" + n;

})

.subscribe(n -> printThreadNameAnd("Subscriber"));
printThreadNameAnd("Done subscribing");
Observable

.fromCallable(() -> {

printThreadNameAnd("Observable");

return 1;

})

.subscribeOn(Schedulers.io())

.filter(n -> {

printThreadNameAnd("Operator 1");

return n == 1;

})
.observeOn(Schedulers.newThread())

.map(n -> {

printThreadNameAnd("Operator 2");

return "A" + n;

})

.subscribe(n -> printThreadNameAnd("Subscriber"));
printThreadNameAnd("Done subscribing");
Observable

.fromCallable(() -> {

printThreadNameAnd("Observable");

return 1;

})

.subscribeOn(Schedulers.io())

.filter(n -> {

printThreadNameAnd("Operator 1");

return n == 1;

})
.observeOn(Schedulers.newThread())

.map(n -> {

printThreadNameAnd("Operator 2");

return "A" + n;

})

.subscribe(n -> printThreadNameAnd("Subscriber"));
printThreadNameAnd("Done subscribing");
Observable

.fromCallable(() -> {

printThreadNameAnd("Observable");

return 1;

})

.subscribeOn(Schedulers.io())

.filter(n -> {

printThreadNameAnd("Operator 1");

return n == 1;

})
.observeOn(Schedulers.newThread())

.map(n -> {

printThreadNameAnd("Operator 2");

return "A" + n;

})

.subscribe(n -> printThreadNameAnd("Subscriber"));
printThreadNameAnd("Done subscribing");
Observable

.fromCallable(() -> {

printThreadNameAnd("Observable");

return 1;

})

.subscribeOn(Schedulers.io())

.filter(n -> {

printThreadNameAnd("Operator 1");

return n == 1;

})
.observeOn(Schedulers.newThread())

.map(n -> {

printThreadNameAnd("Operator 2");

return "A" + n;

})

.subscribe(n -> printThreadNameAnd("Subscriber"));
printThreadNameAnd("Done subscribing");
Observable

.fromCallable(() -> {

printThreadNameAnd("Observable");

return 1;

})

.subscribeOn(Schedulers.io())

.filter(n -> {

printThreadNameAnd("Operator 1");

return n == 1;

})
.observeOn(Schedulers.newThread())

.map(n -> {

printThreadNameAnd("Operator 2");

return "A" + n;

})

.subscribe(n -> printThreadNameAnd("Subscriber"));
printThreadNameAnd("Done subscribing");
Observable

.fromCallable(() -> {

printThreadNameAnd("Observable");

return 1;

})

.subscribeOn(Schedulers.io())

.filter(n -> {

printThreadNameAnd("Operator 1");

return n == 1;

})
.observeOn(Schedulers.newThread())

.map(n -> {

printThreadNameAnd("Operator 2");

return "A" + n;

})

.subscribe(n -> printThreadNameAnd("Subscriber"));
printThreadNameAnd("Done subscribing");
Multithreading
Multithreading
• subscribeOn
• observeOn
• Scheduler
Scheduler
• Schedulers.newThread()
• Schedulers.io()
• Schedulers.computation()
• Schedulers.from(java.util.concurrent.Executor
executor)
Observable.interval(1, TimeUnit.SECONDS)

.take(3)

.subscribe(

n -> printThreadNameAnd("Subscriber"),

e -> System.out.println("Error"),

() -> System.out.println("Completed")

);
Output:
RxComputationThreadPool-1: Subscriber
RxComputationThreadPool-1: Subscriber
RxComputationThreadPool-1: Subscriber
Completed
Scheduler
Scheduler:
interval operates by default
on the computation
Scheduler.
Multithreading
• subscribeOn
• observeOn
• Scheduler
How to think in RxJava
• Introduction
• Operators
• Multithreading
• Resiliency
Resiliency
• Default error handling
Default error handling
Observable.fromCallable(() -> { throw new IOException(); })

.subscribe(

n -> System.out.println(n),

throwable -> printErrorClassName(throwable),

() -> System.out.println("Completed")

);
Output:
Error: IOException
Observable.fromCallable(() -> { throw new IOException(); })

.subscribe(

n -> System.out.println(n),

throwable -> printErrorClassName(throwable),

() -> System.out.println("Completed")

);
Observable.fromCallable(() -> { throw new IOException(); })

.subscribe(

n -> System.out.println(n),

throwable -> printErrorClassName(throwable),

() -> System.out.println("Completed")

);
Observable
throws
Exception
handled
in onError
Default error handling
Observable.just("A")

.map(text -> Integer.parseInt(text))

.subscribe(

n -> System.out.println(n),

throwable -> printErrorClassName(throwable),

() -> System.out.println("Completed")

);
Output:
Error: NumberFormatException
Observable.just("A")

.map(text -> Integer.parseInt(text))

.subscribe(

n -> System.out.println(n),

throwable -> printErrorClassName(throwable),

() -> System.out.println("Completed")

);
Observable.just("A")

.map(text -> Integer.parseInt(text))

.subscribe(

n -> System.out.println(n),

throwable -> printErrorClassName(throwable),

() -> System.out.println("Completed")

);
Operator
throws
Exception
handled
in onError
Resiliency
• Default error handling
• Errors not handled
Errors not handled
Observable.just("A")

.map(text -> Integer.parseInt(text))

.subscribe(

n -> System.out.println(n),

throwable -> { throw new RuntimeException(); },

() -> System.out.println("Completed")

);
Output:
Exception in thread "main"
rx.exceptions.OnErrorFailedException: Error occurred
when trying to propagate error to Observer.onError
Observable.just("A")

.map(text -> Integer.parseInt(text))

.subscribe(

n -> System.out.println(n),

throwable -> { throw new RuntimeException(); },

() -> System.out.println("Completed")

);
Observable.just("A")

.map(text -> Integer.parseInt(text))

.subscribe(

n -> System.out.println(n),

throwable -> { throw new RuntimeException(); },

() -> System.out.println("Completed")

);
onError
throws
Exception
Errors not handled
Observable.just("A")

.map(text -> Integer.parseInt(text))

.subscribe(

n -> System.out.println(n)

);
Output:
Exception in thread "main"
rx.exceptions.OnErrorNotImplementedException
Observable.just("A")

.map(text -> Integer.parseInt(text))

.subscribe(

n -> System.out.println(n)

);
onError
function
missing
Resiliency
• Default error handling
• Errors not handled
• Recovery Mechanisms
Recovery Mechanisms
• Closing the stream gracefully
Closing the stream gracefully
Observable.error(new IOException())

.onErrorReturn(throwable -> -1)

.subscribe(

n -> System.out.println(n),

throwable -> printErrorClassName(throwable),

() -> System.out.println("Completed")

);
Output:
-1
Completed
Observable.error(new IOException())

.onErrorReturn(throwable -> -1)

.subscribe(

n -> System.out.println(n),

throwable -> printErrorClassName(throwable),

() -> System.out.println("Completed")

);
Observable.error(new IOException())

.onErrorReturn(throwable -> -1)

.subscribe(

n -> System.out.println(n),

throwable -> printErrorClassName(throwable),

() -> System.out.println("Completed")

);
handling error
by retuning a value
indicating error
Recovery Mechanisms
• Closing the stream gracefully
• Using a backup
Using a backup
Observable<Integer> aService = Observable
.error(new IOException());

Observable<Integer> backupService = Observable.just(1);


aService

.onErrorResumeNext(backupService)

.subscribe(

n -> System.out.println(n),

throwable -> printErrorClassName(throwable),

() -> System.out.println("Completed")

);
Output:
1
Completed
Observable<Integer> aService = Observable
.error(new IOException());

Observable<Integer> backupService = Observable.just(1);


aService

.onErrorResumeNext(backupService)

.subscribe(

n -> System.out.println(n),

throwable -> printErrorClassName(throwable),

() -> System.out.println("Completed")

);
Observable<Integer> aService = Observable
.error(new IOException());

Observable<Integer> backupService = Observable.just(1);


aService

.onErrorResumeNext(backupService)

.subscribe(

n -> System.out.println(n),

throwable -> printErrorClassName(throwable),

() -> System.out.println("Completed")

);
resuming
with
another service
Recovery Mechanisms
• Closing the stream gracefully
• Using a backup
• Retrying
Retrying
Observable.error(new IOException())

.retryWhen(errorStream ->

Observable.range(1, 3)

.zipWith(errorStream, (n, e) -> n)

.doOnNext(n -> System.out.println("Retry: " + n))

).subscribe(

n -> System.out.println(n),

throwable -> printErrorClassName(throwable),

() -> System.out.println("Completed")

);
Output:
Retry: 1
Retry: 2
Retry: 3
Completed
Observable.error(new IOException())

.retryWhen(errorStream ->

Observable.range(1, 3)

.zipWith(errorStream, (n, e) -> n)

.doOnNext(n -> System.out.println("Retry: " + n))

).subscribe(

n -> System.out.println(n),

throwable -> printErrorClassName(throwable),

() -> System.out.println("Completed")

);
Observable.error(new IOException())

.retryWhen(errorStream ->

Observable.range(1, 3)

.zipWith(errorStream, (n, e) -> n)

.doOnNext(n -> System.out.println("Retry: " + n))

).subscribe(

n -> System.out.println(n),

throwable -> printErrorClassName(throwable),

() -> System.out.println("Completed")

); conditional
retry logic
Recovery Mechanisms
• Closing the stream gracefully
• Using a backup
• Retrying
Resiliency
• Points of failure
• Errors not handled
• Recovery Mechanisms
How to think in RxJava
• Introduction
• Operators
• Multithreading
• Resiliency
• Testing Utilities
Testing Utilities
• TestSubscriber
TestSubscriber
TestSubscriber<Long> testSubscriber =
TestSubscriber.create();
Observable.interval(1, TimeUnit.SECONDS).take(2)

.subscribe(testSubscriber);


testSubscriber.awaitTerminalEvent();

testSubscriber.assertCompleted();
testSubscriber.assertNoErrors();
testSubscriber.assertUnsubscribed();
testSubscriber.assertValueCount(2);

testSubscriber.assertValues(0L, 1L);
Testing Utilities
• TestSubscriber
• TestScheduler
TestScheduler
TestScheduler testScheduler = Schedulers.test();
TestSubscriber<Long> testSubscriber =
TestSubscriber.create();


Observable.interval(1, TimeUnit.SECONDS, testScheduler)
.take(2).subscribe(testSubscriber);


testScheduler.advanceTimeTo(1500, TimeUnit.MILLISECONDS);

testSubscriber.assertValueCount(1);

testSubscriber.assertNotCompleted();


testScheduler.advanceTimeBy(1000, TimeUnit.MILLISECONDS);

testSubscriber.assertValueCount(2);

testSubscriber.assertCompleted();
Testing Utilities
• TestSubscriber
• TestScheduler
How to think in RxJava
• Introduction
• Operators
• Multithreading
• Resiliency
• Testing Utilities
How to think in RxJava
fromCallable
timer
interval justerror
Observable
Subscriber onErroronNext
onCompleted
Observer Pattern
Reactive
map flatMap
timestampfilter
distinctUntilChanged
take
buffer
zip
combineLatest
concatmerge
Functional
observeOnsubscribeOn
Scheduler
io computation newThread
Asynchronous
TestSubscriber
TestScheduler
Resiliency
retry timeout
onErrorResumeNext
Observable
Subscriber onErroronNext
onCompleted
Observer Pattern
Reactive
Concept
fromCallable
timer
interval justerror
Create map flatMap
timestampfilter
distinctUntilChanged
take
buffer
zip
combineLatest
concatmerge
Functional
Operate
observeOnsubscribeOn
Scheduler
io computation newThread
Asynchronous
Resiliency
retry timeout
onErrorResumeNext
TestSubscriber
TestScheduler
Concurrent
Handle
errorsTest
http://reactivex.io/
https://github.com/ReactiveX/RxJava
Questions ?
http://praveer09.github.io
@praveerguptapraveer

More Related Content

PPT
Functional Programming Past Present Future
PDF
Harnessing the Power of Java 8 Streams
PDF
Parallel streams in java 8
PPTX
An Introduction to RxJava
PDF
Reactive programming with RxJava
PPTX
Introduction to rx java for android
PDF
Practical RxJava for Android
PDF
Rxjava meetup presentation
Functional Programming Past Present Future
Harnessing the Power of Java 8 Streams
Parallel streams in java 8
An Introduction to RxJava
Reactive programming with RxJava
Introduction to rx java for android
Practical RxJava for Android
Rxjava meetup presentation

What's hot (20)

PDF
RxJava 2.0 介紹
PDF
Rxjava 介紹與 Android 中的 RxJava
PDF
Reactive Programming for a demanding world: building event-driven and respons...
PDF
Reactive programming on Android
PPT
Java 8 Streams
PDF
RxJava from the trenches
PDF
RxJava on Android
PDF
Practical RxJava for Android
PPTX
Intro to Functional Programming with RxJava
PDF
Building Scalable Stateless Applications with RxJava
PDF
Reactive Android: RxJava and beyond
PDF
Intro to RxJava/RxAndroid - GDG Munich Android
PDF
RxJava in practice
PDF
Streams, Streams Everywhere! An Introduction to Rx
PPTX
Javantura v3 - Going Reactive with RxJava – Hrvoje Crnjak
PDF
RxJava for Android - GDG DevFest Ukraine 2015
PDF
Kotlin Receiver Types 介紹
PDF
Concurrency Utilities in Java 8
PDF
RxJava - introduction & design
PDF
RxJava applied [JavaDay Kyiv 2016]
RxJava 2.0 介紹
Rxjava 介紹與 Android 中的 RxJava
Reactive Programming for a demanding world: building event-driven and respons...
Reactive programming on Android
Java 8 Streams
RxJava from the trenches
RxJava on Android
Practical RxJava for Android
Intro to Functional Programming with RxJava
Building Scalable Stateless Applications with RxJava
Reactive Android: RxJava and beyond
Intro to RxJava/RxAndroid - GDG Munich Android
RxJava in practice
Streams, Streams Everywhere! An Introduction to Rx
Javantura v3 - Going Reactive with RxJava – Hrvoje Crnjak
RxJava for Android - GDG DevFest Ukraine 2015
Kotlin Receiver Types 介紹
Concurrency Utilities in Java 8
RxJava - introduction & design
RxJava applied [JavaDay Kyiv 2016]
Ad

Similar to How to Think in RxJava Before Reacting (20)

PPTX
Rx java in action
PPTX
Javaone 2016 : Supercharge your (reactive) Streams
PDF
Get Reactive: Microservices, Programming, and Systems
PPTX
Rx workshop
PPTX
Luis Atencio on RxJS
PDF
GDG DevFest 2015 - Reactive approach for slowpokes
PDF
Reactive Thinking in Java
PDF
Functional UIs with Java 8 and Vaadin JavaOne2014
PDF
Intro to Rx Java
PDF
A calculus of mobile Real-Time processes
PDF
Rx java2 - Should I use it?
PDF
Introduction to RxJS
PPTX
From zero to hero with the reactive extensions for java script
PPTX
Reactive Java (33rd Degree)
PPTX
PPTX
Rxjs marble-testing
PPTX
Reactive Java (GeeCON 2014)
PDF
Swift & ReactiveX – Asynchronous Event-Based Funsies with RxSwift
PDF
Reactive x
PDF
Reactive Programming in Java and Spring Framework 5
Rx java in action
Javaone 2016 : Supercharge your (reactive) Streams
Get Reactive: Microservices, Programming, and Systems
Rx workshop
Luis Atencio on RxJS
GDG DevFest 2015 - Reactive approach for slowpokes
Reactive Thinking in Java
Functional UIs with Java 8 and Vaadin JavaOne2014
Intro to Rx Java
A calculus of mobile Real-Time processes
Rx java2 - Should I use it?
Introduction to RxJS
From zero to hero with the reactive extensions for java script
Reactive Java (33rd Degree)
Rxjs marble-testing
Reactive Java (GeeCON 2014)
Swift & ReactiveX – Asynchronous Event-Based Funsies with RxSwift
Reactive x
Reactive Programming in Java and Spring Framework 5
Ad

More from IndicThreads (20)

PPTX
Http2 is here! And why the web needs it
ODP
Understanding Bitcoin (Blockchain) and its Potential for Disruptive Applications
PPT
Go Programming Language - Learning The Go Lang way
PPT
Building Resilient Microservices
PPT
App using golang indicthreads
PDF
Building on quicksand microservices indicthreads
PPT
Iot secure connected devices indicthreads
PDF
Real world IoT for enterprises
PPT
IoT testing and quality assurance indicthreads
PDF
Building & scaling a live streaming mobile platform - Gr8 road to fame
PPTX
Internet of things architecture perspective - IndicThreads Conference
PDF
Cars and Computers: Building a Java Carputer
PPTX
Scrap Your MapReduce - Apache Spark
PPT
Continuous Integration (CI) and Continuous Delivery (CD) using Jenkins & Docker
PPTX
Speed up your build pipeline for faster feedback
PPT
Unraveling OpenStack Clouds
PPTX
Digital Transformation of the Enterprise. What IT leaders need to know!
PDF
Architectural Considerations For Complex Mobile And Web Applications
PPTX
Functional Programming With Lambdas and Streams in JDK8
PDF
Changing application demands: What developers need to know
Http2 is here! And why the web needs it
Understanding Bitcoin (Blockchain) and its Potential for Disruptive Applications
Go Programming Language - Learning The Go Lang way
Building Resilient Microservices
App using golang indicthreads
Building on quicksand microservices indicthreads
Iot secure connected devices indicthreads
Real world IoT for enterprises
IoT testing and quality assurance indicthreads
Building & scaling a live streaming mobile platform - Gr8 road to fame
Internet of things architecture perspective - IndicThreads Conference
Cars and Computers: Building a Java Carputer
Scrap Your MapReduce - Apache Spark
Continuous Integration (CI) and Continuous Delivery (CD) using Jenkins & Docker
Speed up your build pipeline for faster feedback
Unraveling OpenStack Clouds
Digital Transformation of the Enterprise. What IT leaders need to know!
Architectural Considerations For Complex Mobile And Web Applications
Functional Programming With Lambdas and Streams in JDK8
Changing application demands: What developers need to know

Recently uploaded (20)

PPTX
Essential Infomation Tech presentation.pptx
PDF
Understanding Forklifts - TECH EHS Solution
PPTX
history of c programming in notes for students .pptx
PDF
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
PDF
System and Network Administration Chapter 2
PPTX
Materi-Enum-and-Record-Data-Type (1).pptx
PPTX
ai tools demonstartion for schools and inter college
PDF
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
PPTX
Operating system designcfffgfgggggggvggggggggg
PPTX
Introduction to Artificial Intelligence
PDF
AI in Product Development-omnex systems
PDF
Design an Analysis of Algorithms I-SECS-1021-03
PDF
medical staffing services at VALiNTRY
PPTX
L1 - Introduction to python Backend.pptx
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
PDF
Design an Analysis of Algorithms II-SECS-1021-03
PDF
Adobe Illustrator 28.6 Crack My Vision of Vector Design
PPTX
ManageIQ - Sprint 268 Review - Slide Deck
PDF
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
PPTX
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
Essential Infomation Tech presentation.pptx
Understanding Forklifts - TECH EHS Solution
history of c programming in notes for students .pptx
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
System and Network Administration Chapter 2
Materi-Enum-and-Record-Data-Type (1).pptx
ai tools demonstartion for schools and inter college
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
Operating system designcfffgfgggggggvggggggggg
Introduction to Artificial Intelligence
AI in Product Development-omnex systems
Design an Analysis of Algorithms I-SECS-1021-03
medical staffing services at VALiNTRY
L1 - Introduction to python Backend.pptx
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
Design an Analysis of Algorithms II-SECS-1021-03
Adobe Illustrator 28.6 Crack My Vision of Vector Design
ManageIQ - Sprint 268 Review - Slide Deck
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
Lecture 3: Operating Systems Introduction to Computer Hardware Systems

How to Think in RxJava Before Reacting

  • 1. Praveer Gupta How to think in RxJava before reacting
  • 2. Reactive Programming “a programming paradigm oriented around data flows and the propagation of change” – Wikipedia
  • 3. Reactive Programming 0 A B 1 fx = A1 + B1 C 2 3 25
  • 4. • Java VM implementation of ReactiveX • An API for asynchronous programming with observable streams What is Rx in RxJava? RxJs Rx.NET RxScala RxClojure RxSwift Rx.rbRxPY & Others
  • 5. • Client Side Applications of RxJava Thread switching Event handling
  • 6. • Client Side • Server Side Applications of RxJava Internal Processing Service A Service B Service C Request Total Request Processing Time Service Boundary Parallel Sequential Response Combine
  • 8. RxJava fromCallable timer interval justerror Observable Subscriber onErroronNext onCompleted Observer Pattern Reactive map flatMap timestampfilter distinctUntilChanged take buffer zip combineLatest concatmerge Functional observeOnsubscribeOn Scheduler io computation newThread Asynchronous TestSubscriber TestScheduler Resiliency retry timeout onErrorResumeNext Observable Subscriber onErroronNext onCompleted Observer Pattern Reactive Concept fromCallable timer interval justerror Create map flatMap timestampfilter distinctUntilChanged take buffer zip combineLatest concatmerge Functional Operate observeOnsubscribeOn Scheduler io computation newThread Asynchronous Resiliency retry timeout onErrorResumeNext TestSubscriber TestScheduler Concurrent Handle errorsTest How to think in RxJava
  • 9. How to think in RxJava • Introduction
  • 10. Introduction • Observer & Iterator Pattern
  • 11. Subscriber (Consumer) Observable (Source) 2 onNext( )2 21 1onNext( )1 Source Consumersubscribe Produces data/event asynchronously Consumes data/event as they arrive Pushes data/event Observer & Iterator Pattern
  • 13. onError( )XX X Observable Subscriber (Source) (Consumer) unsubscribe Pushes error event Observer & Iterator Pattern Error
  • 14. onNext( )1 Observable Subscriber onError( )X onCompleted() Pushing Streams of Data/Events Observer & Iterator Pattern
  • 15. Introduction • Observer & Iterator Pattern • RxJava in Action
  • 16. Subscriber<Integer> subscriber = Subscribers.create(
 n -> System.out.println(n),
 e -> System.out.print("Error"),
 () -> System.out.println("Completed")
 ); Observable<Integer> observable = Observable.just(1, 2, 3); observable.subscribe(subscriber); Subscriber<Integer> subscriber = Subscribers.create(
 n -> System.out.println(n),
 e -> System.out.print("Error"),
 () -> System.out.println("Completed")
 ); Subscriber<Integer> subscriber = Subscribers.create(
 n -> System.out.println(n),
 e -> System.out.println("Error"),
 () -> System.out.println("Completed")
 ); Subscriber<Integer> subscriber = Subscribers.create(
 n -> System.out.println(n),
 e -> System.out.println("Error"),
 () -> System.out.println("Completed")
 ); Subscriber<Integer> subscriber = Subscribers.create(
 n -> System.out.println(n),
 e -> System.out.println("Error"),
 () -> System.out.println("Completed")
 ); Observable<Integer> observable = Observable.just(1, 2, 3); Subscriber<Integer> subscriber = Subscribers.create(
 n -> System.out.println(n),
 e -> System.out.println("Error"),
 () -> System.out.println("Completed")
 ); Observable<Integer> observable = Observable.just(1, 2, 3); RxJava in Action Source Consumer onNext onError onCompleted connect
  • 17. Observable.just(1, 2, 3).subscribe(
 n -> System.out.println(n),
 e -> System.out.println("Error"),
 () -> System.out.println("Completed")
 ); 1 Output: 2 3 Completed RxJava in Action
  • 18. Introduction • Observer & Iterator Pattern • RxJava in Action • Creating Observables
  • 20. Observable.fromCallable(new Callable<String>() {
 @Override
 public String call() throws Exception {
 return "result";
 }
 }).subscribe( n -> System.out.println(n), e -> System.out.println(“Error"), () -> System.out.println("Completed") ); fromCallable Observable.fromCallable(new Callable<String>() {
 @Override
 public String call() throws Exception {
 return "result";
 }
 }).subscribe( n -> System.out.println(n), e -> System.out.println(“Error"), () -> System.out.println("Completed") );
  • 21. Observable.fromCallable(() -> "result"); .subscribe( s -> System.out.println(s), e -> System.out.println("Error"), () -> System.out.println("Completed") ); fromCallable Output: result Completed Observable.fromCallable(() -> "result"); .subscribe( s -> System.out.println(s), e -> System.out.println("Error"), () -> System.out.println("Completed") );
  • 23. Introduction • Observer Pattern • RxJava in Action • Creating Observables
  • 24. How to think in RxJava • Introduction • Operators
  • 28. Observable.interval(1, TimeUnit.SECONDS) .take(2)
 .subscribe( n -> System.out.println(n), e -> System.out.println("Error"), () -> System.out.println("Completed") ); Output: 0 1 Completed Filtering Observable.interval(1, TimeUnit.SECONDS) .take(2)
 .subscribe( n -> System.out.println(n), e -> System.out.println("Error"), () -> System.out.println("Completed") ); Observable.interval(1, TimeUnit.SECONDS) .take(2)
 .subscribe( n -> System.out.println(n), e -> System.out.println("Error"), () -> System.out.println("Completed") );
  • 31. Observable.just("A", "B")
 .flatMap(e -> Observable.just(1, 2).map(n -> e + n))
 .subscribe(
 n -> System.out.println(n),
 e -> System.out.println("Error"),
 () -> System.out.println("Completed")
 ); Output: A1 A2 B1 B2 Completed Transforming Observable.just("A", "B")
 .flatMap(e -> Observable.just(1, 2).map(n -> e + n))
 .subscribe(
 n -> System.out.println(n),
 e -> System.out.println("Error"),
 () -> System.out.println("Completed")
 ); Observable.just("A", "B")
 .flatMap(e -> Observable.just(1, 2).map(n -> e + n))
 .subscribe(
 n -> System.out.println(n),
 e -> System.out.println("Error"),
 () -> System.out.println("Completed")
 );
  • 34. Observable.zip(
 Observable.just("A", "B", "C"),
 Observable.interval(1, TimeUnit.SECONDS),
 (a, n) -> a + n
 ).subscribe(
 n -> System.out.println(n),
 e -> System.out.println("Error"),
 () -> System.out.println("Completed")
 ); Output: A0 B1 C2 Completed Combining Observable.zip(
 Observable.just("A", "B", "C"),
 Observable.interval(1, TimeUnit.SECONDS),
 (a, n) -> a + n
 ).subscribe(
 n -> System.out.println(n),
 e -> System.out.println("Error"),
 () -> System.out.println("Completed")
 );
  • 36. How to think in RxJava • Introduction • Operators • Multithreading
  • 38. Multithreading Observable
 .fromCallable(() -> {
 printThreadNameAnd("Observable");
 return 1;
 })
 .filter(n -> {
 printThreadNameAnd("Operator 1");
 return n == 1;
 })
 .map(n -> {
 printThreadNameAnd("Operator 2");
 return "A" + n;
 })
 .subscribe(n -> printThreadNameAnd(“Subscriber")); printThreadNameAnd("Done subscribing"); Observable Operator 1 Operator 2 Subscriber Observable
 .fromCallable(() -> {
 printThreadNameAnd("Observable");
 return 1;
 })
 .filter(n -> {
 printThreadNameAnd("Operator 1");
 return n == 1;
 })
 .map(n -> {
 printThreadNameAnd("Operator 2");
 return "A" + n;
 })
 .subscribe(n -> printThreadNameAnd(“Subscriber")); printThreadNameAnd("Done subscribing");
  • 39. Observable
 .fromCallable(() -> {
 printThreadNameAnd("Observable");
 return 1;
 })
 .filter(n -> {
 printThreadNameAnd("Operator 1");
 return n == 1;
 })
 .map(n -> {
 printThreadNameAnd("Operator 2");
 return "A" + n;
 })
 .subscribe(n -> printThreadNameAnd(“Subscriber")); printThreadNameAnd("Done subscribing"); Observable
 .fromCallable(() -> {
 printThreadNameAnd("Observable");
 return 1;
 })
 .filter(n -> {
 printThreadNameAnd("Operator 1");
 return n == 1;
 })
 .map(n -> {
 printThreadNameAnd("Operator 2");
 return "A" + n;
 })
 .subscribe(n -> printThreadNameAnd(“Subscriber")); printThreadNameAnd("Done subscribing"); Observable
 .fromCallable(() -> {
 printThreadNameAnd("Observable");
 return 1;
 })
 .filter(n -> {
 printThreadNameAnd("Operator 1");
 return n == 1;
 })
 .map(n -> {
 printThreadNameAnd("Operator 2");
 return "A" + n;
 })
 .subscribe(n -> printThreadNameAnd(“Subscriber")); printThreadNameAnd("Done subscribing"); Observable
 .fromCallable(() -> {
 printThreadNameAnd("Observable");
 return 1;
 })
 .filter(n -> {
 printThreadNameAnd("Operator 1");
 return n == 1;
 })
 .map(n -> {
 printThreadNameAnd("Operator 2");
 return "A" + n;
 })
 .subscribe(n -> printThreadNameAnd(“Subscriber")); printThreadNameAnd("Done subscribing"); Observable
 .fromCallable(() -> {
 printThreadNameAnd("Observable");
 return 1;
 })
 .filter(n -> {
 printThreadNameAnd("Operator 1");
 return n == 1;
 })
 .map(n -> {
 printThreadNameAnd("Operator 2");
 return "A" + n;
 })
 .subscribe(n -> printThreadNameAnd(“Subscriber")); printThreadNameAnd("Done subscribing"); Observable
 .fromCallable(() -> {
 printThreadNameAnd("Observable");
 return 1;
 })
 .filter(n -> {
 printThreadNameAnd("Operator 1");
 return n == 1;
 })
 .map(n -> {
 printThreadNameAnd("Operator 2");
 return "A" + n;
 })
 .subscribe(n -> printThreadNameAnd(“Subscriber")); printThreadNameAnd("Done subscribing"); Observable
 .fromCallable(() -> {
 printThreadNameAnd("Observable");
 return 1;
 })
 .filter(n -> {
 printThreadNameAnd("Operator 1");
 return n == 1;
 })
 .map(n -> {
 printThreadNameAnd("Operator 2");
 return "A" + n;
 })
 .subscribe(n -> printThreadNameAnd(“Subscriber")); printThreadNameAnd("Done subscribing"); Output: main: Observable main: Operator 1 main: Operator 2 main: Subscriber main: Done subscribing RxJava is blocking by default Multithreading
  • 40. Observable
 .fromCallable(() -> {
 printThreadNameAnd("Observable");
 return 1;
 })
 .subscribeOn(Schedulers.io())
 .filter(n -> {
 printThreadNameAnd("Operator 1");
 return n == 1;
 })
 .map(n -> {
 printThreadNameAnd("Operator 2");
 return "A" + n;
 })
 .subscribe(n -> printThreadNameAnd("Subscriber")); printThreadNameAnd("Done subscribing"); Observable
 .fromCallable(() -> {
 printThreadNameAnd("Observable");
 return 1;
 })
 .subscribeOn(Schedulers.io())
 .filter(n -> {
 printThreadNameAnd("Operator 1");
 return n == 1;
 })
 .map(n -> {
 printThreadNameAnd("Operator 2");
 return "A" + n;
 })
 .subscribe(n -> printThreadNameAnd("Subscriber")); printThreadNameAnd("Done subscribing"); Output: main: Done subscribing RxCachedThreadScheduler-1: Observable RxCachedThreadScheduler-1: Operator 1 RxCachedThreadScheduler-1: Operator 2 RxCachedThreadScheduler-1: Subscriber Observable
 .fromCallable(() -> {
 printThreadNameAnd("Observable");
 return 1;
 })
 .subscribeOn(Schedulers.io())
 .filter(n -> {
 printThreadNameAnd("Operator 1");
 return n == 1;
 })
 .map(n -> {
 printThreadNameAnd("Operator 2");
 return "A" + n;
 })
 .subscribe(n -> printThreadNameAnd("Subscriber")); printThreadNameAnd("Done subscribing"); Observable
 .fromCallable(() -> {
 printThreadNameAnd("Observable");
 return 1;
 })
 .subscribeOn(Schedulers.io())
 .filter(n -> {
 printThreadNameAnd("Operator 1");
 return n == 1;
 })
 .map(n -> {
 printThreadNameAnd("Operator 2");
 return "A" + n;
 })
 .subscribe(n -> printThreadNameAnd("Subscriber")); printThreadNameAnd("Done subscribing"); Observable
 .fromCallable(() -> {
 printThreadNameAnd("Observable");
 return 1;
 })
 .subscribeOn(Schedulers.io())
 .filter(n -> {
 printThreadNameAnd("Operator 1");
 return n == 1;
 })
 .map(n -> {
 printThreadNameAnd("Operator 2");
 return "A" + n;
 })
 .subscribe(n -> printThreadNameAnd("Subscriber")); printThreadNameAnd("Done subscribing"); Observable
 .fromCallable(() -> {
 printThreadNameAnd("Observable");
 return 1;
 })
 .subscribeOn(Schedulers.io())
 .filter(n -> {
 printThreadNameAnd("Operator 1");
 return n == 1;
 })
 .map(n -> {
 printThreadNameAnd("Operator 2");
 return "A" + n;
 })
 .subscribe(n -> printThreadNameAnd("Subscriber")); printThreadNameAnd("Done subscribing"); Observable
 .fromCallable(() -> {
 printThreadNameAnd("Observable");
 return 1;
 })
 .subscribeOn(Schedulers.io())
 .filter(n -> {
 printThreadNameAnd("Operator 1");
 return n == 1;
 })
 .map(n -> {
 printThreadNameAnd("Operator 2");
 return "A" + n;
 })
 .subscribe(n -> printThreadNameAnd("Subscriber")); printThreadNameAnd("Done subscribing"); Observable
 .fromCallable(() -> {
 printThreadNameAnd("Observable");
 return 1;
 })
 .subscribeOn(Schedulers.io())
 .filter(n -> {
 printThreadNameAnd("Operator 1");
 return n == 1;
 })
 .map(n -> {
 printThreadNameAnd("Operator 2");
 return "A" + n;
 })
 .subscribe(n -> printThreadNameAnd("Subscriber")); printThreadNameAnd("Done subscribing"); Multithreading
  • 41. Observable
 .fromCallable(() -> {
 printThreadNameAnd("Observable");
 return 1;
 })
 .subscribeOn(Schedulers.io())
 .filter(n -> {
 printThreadNameAnd("Operator 1");
 return n == 1;
 }) .observeOn(Schedulers.newThread())
 .map(n -> {
 printThreadNameAnd("Operator 2");
 return "A" + n;
 })
 .subscribe(n -> printThreadNameAnd("Subscriber")); printThreadNameAnd("Done subscribing"); Output: main: Done subscribing RxCachedThreadScheduler-1: Observable RxCachedThreadScheduler-1: Operator 1 RxNewThreadScheduler-1: Operator 2 RxNewThreadScheduler-1: Subscriber Observable
 .fromCallable(() -> {
 printThreadNameAnd("Observable");
 return 1;
 })
 .subscribeOn(Schedulers.io())
 .filter(n -> {
 printThreadNameAnd("Operator 1");
 return n == 1;
 }) .observeOn(Schedulers.newThread())
 .map(n -> {
 printThreadNameAnd("Operator 2");
 return "A" + n;
 })
 .subscribe(n -> printThreadNameAnd("Subscriber")); printThreadNameAnd("Done subscribing"); Observable
 .fromCallable(() -> {
 printThreadNameAnd("Observable");
 return 1;
 })
 .subscribeOn(Schedulers.io())
 .filter(n -> {
 printThreadNameAnd("Operator 1");
 return n == 1;
 }) .observeOn(Schedulers.newThread())
 .map(n -> {
 printThreadNameAnd("Operator 2");
 return "A" + n;
 })
 .subscribe(n -> printThreadNameAnd("Subscriber")); printThreadNameAnd("Done subscribing"); Observable
 .fromCallable(() -> {
 printThreadNameAnd("Observable");
 return 1;
 })
 .subscribeOn(Schedulers.io())
 .filter(n -> {
 printThreadNameAnd("Operator 1");
 return n == 1;
 }) .observeOn(Schedulers.newThread())
 .map(n -> {
 printThreadNameAnd("Operator 2");
 return "A" + n;
 })
 .subscribe(n -> printThreadNameAnd("Subscriber")); printThreadNameAnd("Done subscribing"); Observable
 .fromCallable(() -> {
 printThreadNameAnd("Observable");
 return 1;
 })
 .subscribeOn(Schedulers.io())
 .filter(n -> {
 printThreadNameAnd("Operator 1");
 return n == 1;
 }) .observeOn(Schedulers.newThread())
 .map(n -> {
 printThreadNameAnd("Operator 2");
 return "A" + n;
 })
 .subscribe(n -> printThreadNameAnd("Subscriber")); printThreadNameAnd("Done subscribing"); Observable
 .fromCallable(() -> {
 printThreadNameAnd("Observable");
 return 1;
 })
 .subscribeOn(Schedulers.io())
 .filter(n -> {
 printThreadNameAnd("Operator 1");
 return n == 1;
 }) .observeOn(Schedulers.newThread())
 .map(n -> {
 printThreadNameAnd("Operator 2");
 return "A" + n;
 })
 .subscribe(n -> printThreadNameAnd("Subscriber")); printThreadNameAnd("Done subscribing"); Observable
 .fromCallable(() -> {
 printThreadNameAnd("Observable");
 return 1;
 })
 .subscribeOn(Schedulers.io())
 .filter(n -> {
 printThreadNameAnd("Operator 1");
 return n == 1;
 }) .observeOn(Schedulers.newThread())
 .map(n -> {
 printThreadNameAnd("Operator 2");
 return "A" + n;
 })
 .subscribe(n -> printThreadNameAnd("Subscriber")); printThreadNameAnd("Done subscribing"); Observable
 .fromCallable(() -> {
 printThreadNameAnd("Observable");
 return 1;
 })
 .subscribeOn(Schedulers.io())
 .filter(n -> {
 printThreadNameAnd("Operator 1");
 return n == 1;
 }) .observeOn(Schedulers.newThread())
 .map(n -> {
 printThreadNameAnd("Operator 2");
 return "A" + n;
 })
 .subscribe(n -> printThreadNameAnd("Subscriber")); printThreadNameAnd("Done subscribing"); Multithreading
  • 43. Scheduler • Schedulers.newThread() • Schedulers.io() • Schedulers.computation() • Schedulers.from(java.util.concurrent.Executor executor)
  • 44. Observable.interval(1, TimeUnit.SECONDS)
 .take(3)
 .subscribe(
 n -> printThreadNameAnd("Subscriber"),
 e -> System.out.println("Error"),
 () -> System.out.println("Completed")
 ); Output: RxComputationThreadPool-1: Subscriber RxComputationThreadPool-1: Subscriber RxComputationThreadPool-1: Subscriber Completed Scheduler Scheduler: interval operates by default on the computation Scheduler.
  • 46. How to think in RxJava • Introduction • Operators • Multithreading • Resiliency
  • 48. Default error handling Observable.fromCallable(() -> { throw new IOException(); })
 .subscribe(
 n -> System.out.println(n),
 throwable -> printErrorClassName(throwable),
 () -> System.out.println("Completed")
 ); Output: Error: IOException Observable.fromCallable(() -> { throw new IOException(); })
 .subscribe(
 n -> System.out.println(n),
 throwable -> printErrorClassName(throwable),
 () -> System.out.println("Completed")
 ); Observable.fromCallable(() -> { throw new IOException(); })
 .subscribe(
 n -> System.out.println(n),
 throwable -> printErrorClassName(throwable),
 () -> System.out.println("Completed")
 ); Observable throws Exception handled in onError
  • 49. Default error handling Observable.just("A")
 .map(text -> Integer.parseInt(text))
 .subscribe(
 n -> System.out.println(n),
 throwable -> printErrorClassName(throwable),
 () -> System.out.println("Completed")
 ); Output: Error: NumberFormatException Observable.just("A")
 .map(text -> Integer.parseInt(text))
 .subscribe(
 n -> System.out.println(n),
 throwable -> printErrorClassName(throwable),
 () -> System.out.println("Completed")
 ); Observable.just("A")
 .map(text -> Integer.parseInt(text))
 .subscribe(
 n -> System.out.println(n),
 throwable -> printErrorClassName(throwable),
 () -> System.out.println("Completed")
 ); Operator throws Exception handled in onError
  • 50. Resiliency • Default error handling • Errors not handled
  • 51. Errors not handled Observable.just("A")
 .map(text -> Integer.parseInt(text))
 .subscribe(
 n -> System.out.println(n),
 throwable -> { throw new RuntimeException(); },
 () -> System.out.println("Completed")
 ); Output: Exception in thread "main" rx.exceptions.OnErrorFailedException: Error occurred when trying to propagate error to Observer.onError Observable.just("A")
 .map(text -> Integer.parseInt(text))
 .subscribe(
 n -> System.out.println(n),
 throwable -> { throw new RuntimeException(); },
 () -> System.out.println("Completed")
 ); Observable.just("A")
 .map(text -> Integer.parseInt(text))
 .subscribe(
 n -> System.out.println(n),
 throwable -> { throw new RuntimeException(); },
 () -> System.out.println("Completed")
 ); onError throws Exception
  • 52. Errors not handled Observable.just("A")
 .map(text -> Integer.parseInt(text))
 .subscribe(
 n -> System.out.println(n)
 ); Output: Exception in thread "main" rx.exceptions.OnErrorNotImplementedException Observable.just("A")
 .map(text -> Integer.parseInt(text))
 .subscribe(
 n -> System.out.println(n)
 ); onError function missing
  • 53. Resiliency • Default error handling • Errors not handled • Recovery Mechanisms
  • 54. Recovery Mechanisms • Closing the stream gracefully
  • 55. Closing the stream gracefully Observable.error(new IOException())
 .onErrorReturn(throwable -> -1)
 .subscribe(
 n -> System.out.println(n),
 throwable -> printErrorClassName(throwable),
 () -> System.out.println("Completed")
 ); Output: -1 Completed Observable.error(new IOException())
 .onErrorReturn(throwable -> -1)
 .subscribe(
 n -> System.out.println(n),
 throwable -> printErrorClassName(throwable),
 () -> System.out.println("Completed")
 ); Observable.error(new IOException())
 .onErrorReturn(throwable -> -1)
 .subscribe(
 n -> System.out.println(n),
 throwable -> printErrorClassName(throwable),
 () -> System.out.println("Completed")
 ); handling error by retuning a value indicating error
  • 56. Recovery Mechanisms • Closing the stream gracefully • Using a backup
  • 57. Using a backup Observable<Integer> aService = Observable .error(new IOException());
 Observable<Integer> backupService = Observable.just(1); 
 aService
 .onErrorResumeNext(backupService)
 .subscribe(
 n -> System.out.println(n),
 throwable -> printErrorClassName(throwable),
 () -> System.out.println("Completed")
 ); Output: 1 Completed Observable<Integer> aService = Observable .error(new IOException());
 Observable<Integer> backupService = Observable.just(1); 
 aService
 .onErrorResumeNext(backupService)
 .subscribe(
 n -> System.out.println(n),
 throwable -> printErrorClassName(throwable),
 () -> System.out.println("Completed")
 ); Observable<Integer> aService = Observable .error(new IOException());
 Observable<Integer> backupService = Observable.just(1); 
 aService
 .onErrorResumeNext(backupService)
 .subscribe(
 n -> System.out.println(n),
 throwable -> printErrorClassName(throwable),
 () -> System.out.println("Completed")
 ); resuming with another service
  • 58. Recovery Mechanisms • Closing the stream gracefully • Using a backup • Retrying
  • 59. Retrying Observable.error(new IOException())
 .retryWhen(errorStream ->
 Observable.range(1, 3)
 .zipWith(errorStream, (n, e) -> n)
 .doOnNext(n -> System.out.println("Retry: " + n))
 ).subscribe(
 n -> System.out.println(n),
 throwable -> printErrorClassName(throwable),
 () -> System.out.println("Completed")
 ); Output: Retry: 1 Retry: 2 Retry: 3 Completed Observable.error(new IOException())
 .retryWhen(errorStream ->
 Observable.range(1, 3)
 .zipWith(errorStream, (n, e) -> n)
 .doOnNext(n -> System.out.println("Retry: " + n))
 ).subscribe(
 n -> System.out.println(n),
 throwable -> printErrorClassName(throwable),
 () -> System.out.println("Completed")
 ); Observable.error(new IOException())
 .retryWhen(errorStream ->
 Observable.range(1, 3)
 .zipWith(errorStream, (n, e) -> n)
 .doOnNext(n -> System.out.println("Retry: " + n))
 ).subscribe(
 n -> System.out.println(n),
 throwable -> printErrorClassName(throwable),
 () -> System.out.println("Completed")
 ); conditional retry logic
  • 60. Recovery Mechanisms • Closing the stream gracefully • Using a backup • Retrying
  • 61. Resiliency • Points of failure • Errors not handled • Recovery Mechanisms
  • 62. How to think in RxJava • Introduction • Operators • Multithreading • Resiliency • Testing Utilities
  • 64. TestSubscriber TestSubscriber<Long> testSubscriber = TestSubscriber.create(); Observable.interval(1, TimeUnit.SECONDS).take(2)
 .subscribe(testSubscriber); 
 testSubscriber.awaitTerminalEvent();
 testSubscriber.assertCompleted(); testSubscriber.assertNoErrors(); testSubscriber.assertUnsubscribed(); testSubscriber.assertValueCount(2);
 testSubscriber.assertValues(0L, 1L);
  • 66. TestScheduler TestScheduler testScheduler = Schedulers.test(); TestSubscriber<Long> testSubscriber = TestSubscriber.create(); 
 Observable.interval(1, TimeUnit.SECONDS, testScheduler) .take(2).subscribe(testSubscriber); 
 testScheduler.advanceTimeTo(1500, TimeUnit.MILLISECONDS);
 testSubscriber.assertValueCount(1);
 testSubscriber.assertNotCompleted(); 
 testScheduler.advanceTimeBy(1000, TimeUnit.MILLISECONDS);
 testSubscriber.assertValueCount(2);
 testSubscriber.assertCompleted();
  • 68. How to think in RxJava • Introduction • Operators • Multithreading • Resiliency • Testing Utilities
  • 69. How to think in RxJava fromCallable timer interval justerror Observable Subscriber onErroronNext onCompleted Observer Pattern Reactive map flatMap timestampfilter distinctUntilChanged take buffer zip combineLatest concatmerge Functional observeOnsubscribeOn Scheduler io computation newThread Asynchronous TestSubscriber TestScheduler Resiliency retry timeout onErrorResumeNext Observable Subscriber onErroronNext onCompleted Observer Pattern Reactive Concept fromCallable timer interval justerror Create map flatMap timestampfilter distinctUntilChanged take buffer zip combineLatest concatmerge Functional Operate observeOnsubscribeOn Scheduler io computation newThread Asynchronous Resiliency retry timeout onErrorResumeNext TestSubscriber TestScheduler Concurrent Handle errorsTest