Reactive

Programming

So what's reactive programming?

Reactive Programming is:

  • Programming 
  • With
  • Asynchronous
  • Event Streams

So...?

  • solve asynchronous problems easier 
  • with cleaner code
  • by writing less boilerplate
  • and also avoid callback-hells
  • "LINQ for sequences of events"

So you get to:

The Basics:

 

Observables

&

Subscribers

Observable<T>

  • First, an Observable<T> emits 0-* events of type T
  • Then it emits a 'Complete' signal...
  • ... OR it emits an 'Error' signal
  • ... OR it's and endless stream of events

Creating an Observable

Observable<String> myObservable = Observable.create(
    new Observable.OnSubscribe<String>() {
        @Override
        public void call(Subscriber<? super String> sub) {
            sub.onNext("Serious Rr business.");
            sub.onCompleted();
        }
    }
);

Subscriber<T>

  • Subscriber = listener of an Rx stream
  • Reacts to incoming events & signals
  • Can unsubscribe from the stream
Subscriber<String> mySubscriber = new Subscriber<String>() {
    @Override
    public void onNext(String s) { System.out.println(s); }

    @Override
    public void onCompleted() { }

    @Override
    public void onError(Throwable e) { }
};

Let's connect all this

Observable<String> myObservable = Observable.create(
    new Observable.OnSubscribe<String>() {
        @Override
        public void call(Subscriber<? super String> sub) {
            sub.onNext("Serious Rr business.");
            sub.onCompleted();
        }
    }
);

Subscriber<String> mySubscriber = new Subscriber<String>() {
    @Override
    public void onNext(String s) { System.out.println(s); }

    @Override
    public void onCompleted() { }

    @Override
    public void onError(Throwable e) { }
};

myObservable.subscribe(mySubscriber);
// Output: "Serious Rr business."

Advantages so far

  • It seems to be a clean, generic & standard pattern for async problems
  • ... and not much else, yet

Async - do we care? 

  • Network requests
  • Disk I/O
  • Bitmap manipulation
  • Calculation-intensive BL
  • UI layout
  • Every single UI interaction
  • Sensor input
  • Model state changes
  • Device configuration changes
  • And the list goes on

The Observable pattern maps easily to these problems

We sure do:

The real deal: operators

Operators

  • transform
  • combine
  • filter
  • delay
  • debounce
  • etc.

With operators we can:

our Rx Streams -> huge flexibility.

Rx Operators - Map

Rx Operators - Buffer

Rx Operators - Filter

Rx Operators -  Zip

Rx Operators - CombineLatest

Win #1

Rx helps avoiding callback-hells by chaining streams

Win #2

Easier combination of async processes with stream primitives

Win #3

Better error handling

  • Errors are passed cleanly towards the Subscriber
  • Error handling code can remain in the Subscriber!

Oh there's more:

Scheduling

By default an Observable is synchronous!

Scheduling

  • The Subscriber can control threading via operators & Schedulers

  • .subscribeOn(<Scheduler>) -> work will be done on this Scheduler

  • .observeOn(<Scheduler>) -> events will be received on this Scheduler

Schedulers

  • Schedulers.newThread() -> new thread for each job

  • Schedulers.immediate() -> execute job in current context

  • Schedulers.from(<Executor>) -> use any Executor for job execution

  • AndroidSchedulers.mainThread() -> execute job on UI thread

  • Etc...

Schedulers - example

Observable.just(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
                .filter(new Func1<Integer, Boolean>() {
                    @Override
                    public Boolean call(Integer value) {
                        return value % 2 == 0;
                    }
                })
                .buffer(3)
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<List<Integer>>() {
                    @Override
                    public void call(List<Integer> value) {
                        Log.d("Out", "Got: " + value);
                    }
                });
Output:

Got: [2, 4, 6]
Got: [8, 10]

How we use RxJava in Go Android

Recent Place Handling

  • We need to store the last X origin & destination places the user selected
  • Simple SharedPrefs-based storage (XML)
  • In general: most of our DataHandlers are Reactive

Route Categorization

  • We present possible travel destinations, with prices attached
  • Need to put them into price categories of fixed sizes

Geo Lookups

  • We need to get details Place information from the Geo Service
  • IATA code (String) -> Place ID (int) conversion also needed

UI Interactions

  • Click listeners, Text Changed listeners are Reactive where it makes sense
  • Makes sense = need to integrate them into Rx streams
  • E.g.: AutoSuggest EditText text changed event throttling

Sorting / Filtering Architecture

  • Search Configurations
  • Filter Configurations
  • Dataset polling
  • Search config change -> restart polling
  • New result polled OR filter config change -> Refilter dataset / Refresh UI
  • State for collection (dirty / complete)
  • Calculating tags and rating
  • Sort chain, Filter pipeline
  • Wrapping result with statistics
  • State for filters

Summary

More, Rx++ topics

  • Hot and Cold Observables
  • Subjects
  • Backpressure
  • More complex operators
  • Custom-built operators
  • RxJava plugins
  • Patterns / anti-patterns
  • ...

So what are the cons?

  • Initial learning curve is a bit steep without guidance
  • A bit hard to find good advanced docs
  • You need to know what you're doing - cargo cult programming is especially dangerous with Rx
  • Adds debugging complexity

And most importantly

  • Rx is - yet again - not a silver bullet, don't use it for everything
  • You're exchanging lower level problems to higher level problems
  • We believe that in most cases this exchange is worth it

Thanks for watching!

Q & A?

Reactive Programming Intro

By rzsombor

Reactive Programming Intro

  • 653