Reactive programming with RxJava

77
Reactive Programming with RxJava Jobaer Chowdhury Technical Project Manager, Cefalo Presented @ JUGBD 6.0 (25/02/2017)

Transcript of Reactive programming with RxJava

Page 1: Reactive programming with RxJava

Reactive Programming with RxJava

Jobaer ChowdhuryTechnical Project Manager, Cefalo

Presented @ JUGBD 6.0 (25/02/2017)

Page 2: Reactive programming with RxJava

Writing concurrent code in Java is hard.

Page 3: Reactive programming with RxJava

Writing correct concurrent code is even harder

Page 4: Reactive programming with RxJava

Unless you’ve read this from cover to cover, twice :-)

Page 5: Reactive programming with RxJava

What is RxJava?

Page 6: Reactive programming with RxJava

What is RxJava?- A library for composing asynchronous and event based programs

We can write concurrent code using RxJava library without worrying about low level threads, locks and synchronization.

Page 7: Reactive programming with RxJava

Brief history or RxReactive Extensions: first introduced by Microsoft

RxJava: the jvm implementation was first developed by Netflix

Current version is 2.x

(I’ll talk about version 1.x here)

Page 8: Reactive programming with RxJava

RxJava: Most starred java repository on Github

Page 9: Reactive programming with RxJava
Page 10: Reactive programming with RxJava

Many implementationsRx.NET

RxJava

RxJS

RxScala

RxClojure

…. And some others

Page 11: Reactive programming with RxJava

So let’s get started ...

Page 12: Reactive programming with RxJava

Observable<T> is the heart of RxJava

Page 13: Reactive programming with RxJava

Observable<T>… a flowing sequence of values

… a stream of events

An observer can subscribe to the Observable

The Observable may call onNext(), onError() or onCompleted() on the observer

Page 14: Reactive programming with RxJava

Let’s compare Observables to Iterables

Page 15: Reactive programming with RxJava

We all know Iterables, right?Iterable<T> { Iterator<T> iterator();}

Iterator<T> {Boolean hasNext();T next();

}

Page 16: Reactive programming with RxJava

Observable duality with Iterable Iterable<T>, Iterator<T>

● Get an iterator● hasNext(), next()● Pull based● Sync

Observable<T>, Observer<T>

● Subscribe an observer● onNext(), onError(), onCompleted()● Push based ● Async

Page 17: Reactive programming with RxJava

Observable<T> examples● Observable<Tweet> ● Observable<Temperature> ● Observable<Person>● Observable<HttpResponse>● Observable<MouseEvent>

….. and so on

Page 18: Reactive programming with RxJava

Hello Observable!Let’s create an Observable<String> that will emit “Hello, world!”

Observable<String> hello = Observable.create(obs -> {obs.onNext(“Hello, world!”);

});

Page 19: Reactive programming with RxJava

And we can subscribe to it ...Observable<String> hello = Observable.create(obs -> {

obs.onNext(“Hello, world!”);});

hello.subscribe(s -> {System.out.println(s);

});

Page 20: Reactive programming with RxJava

We can simplify the creation here Observable<String> hello = Observable.just(“Hello, World!”);

Page 21: Reactive programming with RxJava

We can also handle errors and completed eventObservable<String> hello = Observable.just(“Hello, World!”);hello.subscribe( val -> {System.out.println(val);}, error -> {System.out.println(“Error occurred”);}, () -> { System.out.println(“Completed”)};})

Page 22: Reactive programming with RxJava

We’ve seen how we can create Observables, and how to consume them.

Page 23: Reactive programming with RxJava

Let’s see how we can modify/operate on Observables

Page 24: Reactive programming with RxJava
Page 25: Reactive programming with RxJava

Observable.filter exampleObservable<Integer> numbers = Observable.just(1, 2, 3, 4, 5, 6);Observable<Integer> result = numbers.filter(num -> num % 2 == 0);

// the result will contain 2, 4, 6 inside the Observables

Page 26: Reactive programming with RxJava
Page 27: Reactive programming with RxJava

Observable.map example// We have a function that gives us an Observable of intsObservable<Integer> ids = searchForArticles(“dhaka”);

// another function that takes an int, and returns an articleArticle loadArticle(Integer articleId) {...}

Observable<Article> result = ids.map(id -> loadArticle(id));

Page 28: Reactive programming with RxJava
Page 29: Reactive programming with RxJava

Observable.flatMap example// We have a function that gives us an Observable of intsObservable<Integer> ids = searchForArticles(“dhaka”);

// and a function returns an article wrapped inside ObservableObservable<Article> loadArticle(Integer articleId) {...}

Observable<Article> result = ids.flatMap(id -> loadArticle(id));

Page 30: Reactive programming with RxJava

Map vs. flatMap

Page 31: Reactive programming with RxJava

Map vs. flatMap exampleObservable<Integer> ids = searchForArticles(“dhaka”);Observable<Article> loadArticle(Integer articleId) {...}

Observable<Observable<Article>> res = ids.map(this::loadArticle);Observable<Article> result = ids.flatMap(this::loadArticle);

Page 32: Reactive programming with RxJava
Page 33: Reactive programming with RxJava

There are many more operators ...

Page 34: Reactive programming with RxJava

Let’s use Observables to solve a real world problem

Page 35: Reactive programming with RxJava

A real world example Let’s assume we are working for a news service. And we have the following requirements.

● Do a search for a term on the search server. The search server will return some ids

● For each id load the news article from db.● For each id find out how many likes the article has on social network● Merge the result from above two steps and send it to view layer

Page 36: Reactive programming with RxJava

Let’s assume we have the following (sync) APIList<Integer> searchForArticles(String query)PersistentArticle loadArticle(Integer articleId)Integer fetchLikeCount(Integer articleId)

…. and we can create article by using the db object and like count Article result = new Article(PersistentArticle, Integer)

Page 37: Reactive programming with RxJava

One way of solving itList<Integer> searchResult = searchForArticles(“dhaka”);List<Article> result = new ArrayList<>();for(Integer id : searchResult) { PersistentArticle pa = loadArticle(id) Integer likes = fetchLikeCount(id) result.add(new Article(pa, likes));}return result;

Page 38: Reactive programming with RxJava

Do you see any problem with this code?

Page 39: Reactive programming with RxJava

It’s sequential, and may take some time to run.

Page 40: Reactive programming with RxJava
Page 41: Reactive programming with RxJava

When an article is loading, nothing prevents us from fetching the like count

of that article, or loading another article, right?

Page 42: Reactive programming with RxJava
Page 43: Reactive programming with RxJava

A concurrent solution may save us running time. And we can use

Observables to do so.

Page 44: Reactive programming with RxJava

Let’s try to use Observables now

Page 45: Reactive programming with RxJava

Let’s assume now we have an async APIObservable<Integer> searchForArticles(String query)Observable<PersistentArticle> loadArticle(Integer articleId)Observable<Integer> fetchLikeCount(Integer articleId)

And we need to come up with the result as the following type.

Observable<Article> result = … ;

// We can use the result like following result.subscribe(article -> {//update the view with it});

Page 46: Reactive programming with RxJava

Don’t worry about how the async API was implemented. Just assume it is

present.

(If we only have a sync api, we can still make it async by wrapping things inside Observables, using Observable.create, just etc.)

Page 47: Reactive programming with RxJava

First step: do the searchObservable<Integer> ids = searchForArticles(String query);

….

For each id we need to load the article and fetch the like count.

Page 48: Reactive programming with RxJava

How do we get the ids out from the Observable?

Page 49: Reactive programming with RxJava

We don’t, instead we apply some operator to transform the source

Observable to a different one

Page 50: Reactive programming with RxJava

Let’s go back to few slides ago, and see how we solved the problem sequentially

Page 51: Reactive programming with RxJava

The traditional solution ... List<Integer> searchResult = searchForArticles(“dhaka”);List<Article> result = new ArrayList<>();for(Integer id : searchResult) { PersistentArticle pa = loadArticle(id) Integer likes = fetchLikeCount(id) result.add(new Article(pa, likes));}return result;

Page 52: Reactive programming with RxJava
Page 53: Reactive programming with RxJava

But we don’t do it like this in rx

Page 54: Reactive programming with RxJava
Page 55: Reactive programming with RxJava

Many Observable operators take lambda as parameter.

And we can get the item from inside the Observable box as a parameter of our

supplied lambda.

Page 56: Reactive programming with RxJava

In case of Observable.filterObservable<Integer> numbers = Observable.just(1, 2, 3, 4, 5, 6);numbers.filter(num -> num % 2 == 0);

// The Observable.filter operator takes a lambda as parameter// We pass it a lambda// Our supplied lambda will be called for each of the item// So here the parameter “num” will represent an item inside the box// This is how we get things out from Observable box.

Page 57: Reactive programming with RxJava

So, let’s get back to the original questionObservable<Integer> ids = searchForArticles(String query);

….

For each id we need to load the article and fetch the like count.

Page 58: Reactive programming with RxJava

Now we know we need to apply some operator, which one?

Page 59: Reactive programming with RxJava

We have to apply flatMapObservable<Integer> ids = searchForArticles(query);ids.flatMap(id -> {

// do something with the id ... });

So, by applying flatMap, we somehow get the item from inside the Observable box, as the parameter of our lambda.

Page 60: Reactive programming with RxJava

We have to apply flatMapObservable<Integer> ids = searchForArticles(query);ids.flatMap(id -> {

Observable<PersistentArticle> arts = loadArticle(id);Observable<Integer> likes = fetchLikeCount(id);

//how do we get the article out from inside Observable?});

Page 61: Reactive programming with RxJava

We need to apply flatMap again ...Observable<Integer> ids = searchForArticles(query);ids.flatMap(id -> {

Observable<PersistentArticle> arts = loadArticle(id);Observable<Integer> likes = fetchLikeCount(id);

return arts.flatMap(art -> {// and now we need to get the likes out

});})

Page 62: Reactive programming with RxJava

And flatMap again ...Observable<Integer> ids = searchForArticles(query);ids.flatMap(id -> {

Observable<PersistentArticle> arts = loadArticle(id);Observable<Integer> likes = fetchLikeCount(id);return arts.flatMap(art -> {

return likes.flatMap(like -> { // now we have everything to make an Article object// so what do we return here? A new Article()?});

});})

Page 63: Reactive programming with RxJava

We need to wrap the result inside ObservableObservable<Integer> ids = searchForArticles(query);ids.flatMap(id -> {

Observable<PersistentArticle> arts = loadArticle(id);Observable<Integer> likes = fetchLikeCount(id);return arts.flatMap(art -> {

return likes.flatMap(like -> { return Observable.just(new Article(art, like));

}); });

})

Page 64: Reactive programming with RxJava

We can remove some nesting here ...

Page 65: Reactive programming with RxJava
Page 66: Reactive programming with RxJava

Alternate version using zipObservable<Integer> ids = searchForArticles(query);ids.flatMap(id -> {

Observable<PersistentArticle> arts = loadArticle(id);Observable<Integer> likes = fetchLikeCount(id);return Observable.zip(arts, likes, (art, lc) -> {

return new Article(art, lc);});

});})

Page 67: Reactive programming with RxJava

Using the full power of Java 8 … searchForArticles(query).flatMap(id -> {

return zip(loadArticle(id), fetchLikeCount(id), Article::new); });});

Page 68: Reactive programming with RxJava

Using the full power of Java 8 … searchForArticles(query).flatMap(id -> {

return zip(loadArticle(id), fetchLikeCount(id), Article::new); });});

This is the solution we desire. I find this code beautiful. And it’s (mostly) concurrent (depending on the implementation of the search, load, etc.).

Page 69: Reactive programming with RxJava

Keep these in mind while using RxJava ● Observables can emit zero, one or more items ● Observables can be of infinite stream of values/events ● Observables can complete without returning anything, Observable.empty().● Observables can emit some items and then call onError() to terminate

abnormally● If onError() is called, then onCompleted will not be called

Page 70: Reactive programming with RxJava

Keep these in mind while using RxJava ● Observables are by default lazy. If no subscriber is subscribed, then nothing

will be executed. ● By default they run in the same thread from which the subscriber is called ● You can change the subscriber thread by calling subscribeOn()● You can change the observer thread by calling observeOn()● There are some built in Schedulers (similar to thread pool). For example

Schedulers.io(), Schedulers.computation().● A single Observable issues notifications to observers serially (not in parallel).

Page 71: Reactive programming with RxJava

A better version of the previous code

searchForArticles(query).flatMap(id -> {return Observable.just(id)

.subscribeOn(Schedulers.io())

.flatMap(i ->{return zip(loadArticle(i),

fetchLikeCount(i), Article::new);

}); });});

In fact this is the concurrent version, although it lost it’s beauty a bit :-) Hoping to cover this in a future session.

Page 72: Reactive programming with RxJava

When you have multiple async or concurrent things, depending on each

other, RxJava may be a good candidate.

Page 73: Reactive programming with RxJava

I only covered the basics, there are way more to learn …

Page 74: Reactive programming with RxJava

Advanced topics (maybe in some future sessions) A whole lot more operators

Subjects

Schedulers

Backpressure

Implementing custom operators

Page 76: Reactive programming with RxJava

Reference● Collection of all tutorials, http://reactivex.io/tutorials.html● Reactive programming with RxJava book,

http://shop.oreilly.com/product/0636920042228.do● The RxJava contract, http://reactivex.io/documentation/contract.html

Page 77: Reactive programming with RxJava

Thank you!