RxJava Schedulers Cheat Sheet

avatar
Michał Klimczak
RxJava Schedulers Cheat Sheet

So you want to schedule, huh?

TL;DR, take me to the code already!

Rx programming is hard. It’s hard at the beginning and then it gets even harder. In Future Mind we have begun our journey with RxJava more than two years ago and even now we learn new things every day. I’ve seen many developers having difficulties with fully grasping relatively simple problems concerning reactive programming. One of those problems is proper reactive task scheduling.

The way RxJava handles multithreading is a result of one of the most beautiful and useful API designs. The simplicity of switching threads between the links of a reactive chain surely contributed to the library’s popularity. All we have to do is to assign a Scheduler to a specific task. How do we do it? We use observeOn() or subscribeOn(). Anyone who used Retrofit with RxJava knows how to handle those basic examples:
getUsers()
  .subscribeOn(Schedulers.io())
  .observeOn(AndroidSchedulers.mainThread())
  .subscribe({ showUsers(it) })

You probably know exactly what happens here. Just a reminder: getUsers() gets called on a background thread (Schedulers.io()), and showUsers() method is called on the main UI thread (AndroidSchedulers.mainThread()). Easy?

What if you have a scenario where you first react to user pressing a button (mainThread()), then load a list from the web (io())? Write each item from the list to database (io()) and wait a few milliseconds (computation()) before notifying view about a change (mainThread()). Finally, notify the view again about the list having been successfully processed (mainThread()). Where do you put all those observeOn() and subscribeOn()? You know? Congratulations, you don’t need the cheat sheet!

Well, not everybody is a smartass like you. That’s why we’ve put together a quick code snippet along with a cheat sheet, so that we have it close at hand whenever someone has any trouble with schedulers.

Cheat sheet

Download as a super duper handy PDF

It’s written in Kotlin and uses RxJava2 but these principles apply to all ReactiveX flavours. It's also much more readable in the PDF form above, because it has colours and everything. Without the colours, you have to be, like, super knowledgeable about dogs being mammals, crocodiles being reptiles etc.

Completable.fromCallable { animalsMaker.makeCat(getThread()) }
  .doOnComplete { animalsMaker.makeDog(getThread()) }
  .observeOn(scheduler(FISH))
  .andThen(Completable.fromCallable { animalsMaker.makeShark(getThread()) })
  .andThen(
    Completable.fromCallable { animalsMaker.makeChicken(getThread()) }
      .subscribeOn(scheduler(BIRDS))
      .andThen(Completable.fromCallable { animalsMaker.makeDuck(getThread()) })
    )
  .andThen(Completable.fromCallable { animalsMaker.makePenguin(getThread()) })
  .subscribeOn(scheduler(MAMMALS))
  .subscribeOn(scheduler(AMPHIBIANS))
  .observeOn(scheduler(REPTILES))
  .doOnComplete { animalsMaker.makeCrocodile(getThread()) }

Basics

  • observeOn() always works downstream — it defines the Scheduler for the tasks following it.

  • subscribeOn() generally defines on what scheduler the first task in the chain starts (e.g. makeCat() is called on MAMMALS).

Nested chains

  • A nested chain is by default subscribed on the preceding Scheduler, but this can be changed with a call to subscribeOn(). In other words, makeChicken() would be subscribed on FISH by default, but is explicitly subscribed on BIRDS instead.

  • The Scheduler of a nested chain defines the Scheduler for the following tasks of outer chain. That is why makePenguin() is called on BIRDS Scheduler.

Watch out!

  • Some operators (e.g. delay(), timer()) have a default Scheduler, which can affect the following parts of the chain quietly.

  • In the example above the AMPHIBIANS Scheduler is never used, because it’s overridden by MAMMALS, but there are special cases where multiple subscribeOn() make sense, e.g. when using doOnSubscribe() — you can explore them with Maciek Górski’s presentation.

The cheat sheet is based on a code that we’ve made available to you to play with. Have fun and pay special attention not to mess crocodile and dog on the same scheduler (brrr).

Authors

avatar

Michał Klimczak

blog comments powered by Disqus
3 min. read
50%

More to discover

avataravataravatar
Karolina Antonowicz, Miłosz Michałowski-Żuk, Mikołaj Saik

What are mobile push notifications and what are the best practices for introducing them?

Mobile push notifications are becoming increasingly more popular and are starting to be considered as one of the more common communication channels, while being equally if not even more functional than the others.
10 min. read
avataravatar
Karolina Antonowicz, Mikołaj Saik

Indoor navigation and the best ways to implement

Everyone of us has probably experienced the situation of leaving a store with empty hands. According to the Retailtouchpoints, nearly 96% of shoppers leave a store without making a purchase at least once in their lifetime.
8 min. read

Is there anything we can do for you?

We use cookies to enhance your experience. Read more about cookies in our privacy policy. Agree