how to think in rxjava before reacting

71
Praveer Gupta How to think in RxJava before reacting

Upload: indicthreads

Post on 09-Jan-2017

306 views

Category:

Software


2 download

TRANSCRIPT

Praveer Gupta

How to think in

RxJavabefore reacting

Reactive Programming

“a programming paradigm oriented around data flows and the propagation of change”

– Wikipedia

Reactive Programming

0A B

1

fx = A1 + B1

C2 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

SequentialResponse

Combine

RxJava

Observable

Subscriber

observeOn

subscribeOn

fromCallable

timer

interval

map

flatMaptimestampfilter

distinctUntilChanged

justerror

onErroronNextonCompleted

take

buffer

zip

combineLatest

concatmerge

Scheduler

iocomputation

newThread

Observer Pattern

Reactive

Functional

Asynchronous

Resiliency

TestSubscriber

TestScheduler

RxJavafromCallable

timer

interval justerror

ObservableSubscriber onErroronNext

onCompletedObserver Pattern

Reactivemap flatMap

timestampfilterdistinctUntilChanged

takebuffer

zipcombineLatest

concatmerge

Functional

observeOnsubscribeOnScheduler

io computation newThread

AsynchronousTestSubscriber

TestScheduler

Resiliencyretry timeout

onErrorResumeNext

ObservableSubscriber onErroronNext

onCompletedObserver Pattern

Reactive

Concept

fromCallabletimer

interval justerrorCreate map flatMap

timestampfilterdistinctUntilChanged

takebuffer

zipcombineLatest

concatmerge

Functional

Operate

observeOnsubscribeOnScheduler

io computation newThread

Asynchronous

Resiliencyretry timeout

onErrorResumeNextTestSubscriber

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 ActionSource

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") );

1Output:

23Completed

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/DataCompletion

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

FilteringObservable.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

TransformingObservable

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

TransformingObservable.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

CombiningObservable.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

MultithreadingObservable .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: SubscriberObservable

.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: SubscriberObservable

.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 handlingObservable.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

Exceptionhandled

in onError

Default error handlingObservable.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 handledObservable.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 handledObservable.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 gracefullyObservable.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 backupObservable<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

RetryingObservable.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

TestSubscriberTestSubscriber<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

TestSchedulerTestScheduler 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 RxJavafromCallable

timer

interval justerror

ObservableSubscriber onErroronNext

onCompletedObserver Pattern

Reactivemap flatMap

timestampfilterdistinctUntilChanged

takebuffer

zipcombineLatest

concatmerge

Functional

observeOnsubscribeOnScheduler

io computation newThread

AsynchronousTestSubscriber

TestScheduler

Resiliencyretry timeout

onErrorResumeNext

ObservableSubscriber onErroronNext

onCompletedObserver Pattern

Reactive

Concept

fromCallabletimer

interval justerrorCreate map flatMap

timestampfilterdistinctUntilChanged

takebuffer

zipcombineLatest

concatmerge

Functional

Operate

observeOnsubscribeOnScheduler

io computation newThread

Asynchronous

Resiliencyretry timeout

onErrorResumeNextTestSubscriber

TestScheduler Concurrent

Handle

errorsTest

http://reactivex.io/

https://github.com/ReactiveX/RxJava

Questions ?http://praveer09.github.io

@praveerguptapraveer