How RxJava reduced our sync time between device and server
There are a lot of ways to periodically sync local data with a backend server without opening up the app. At Practo, we use the sync adapter framework (SyncAdapters) along with a push messaging service. This helps our app to support offline mode and provides a great user experience.
Diving deep…
A periodic sync is setup which makes a series of network calls and get’s the latest chunks of data for each entity eg: patients, appointments, etc based on the last synced timestamp. This doesn’t go well with The Rules of Networking as it makes several network calls. Ideally this should be handled by a single network call to the server and the client should have the ability to parse huge chunks of JSON or rather stream it. [Something which we want to achieve]. We could also use something like Protocol buffers and save the network latency. But this calls for another big discussion with the backend team. Also there could be an end point which gives latest timestamp for each entity and we could make only selective network calls reducing the number of network calls. (This is WIP and will reduce our sync time even further)
So the current scenario is 30+ network calls in sequence during a periodic sync. Let’s say on an average a network request takes x seconds. So the time taken is 30 * x seconds. (-_-) that’s bad.
The flow looks like this
To improve our sync time we could go with two options
- Get the latest data for all the entities(30+) in a single network request. This request would add load to our server and the chances are the request might get timed out. (ruled out)
- Make those 30+ network calls in parallel and the sync adapter can be in a blocking state waiting for all those requests to complete.(✓)
For the option (2) we needed a framework component which made our job easier. We started looking at all possible concurrency APIs. AsyncTask and ThreadExecutors were ruled as too much of boiler plate code.
This is what we wanted
Solution → RxJava
Quoting Amit Shekhar ‘s post
What is RxJava?
RxJava is used for reactive programming. In reactive programming, the consumer reacts to the data as it comes in. Reactive programming allows for event changes to propagate to registered observers.
And I believe:
RxJava is an art and endless possibilities await those who can master it.
Learn & read more here. It took us some time to understand it. Those marble diagrams made the learning easier though. But once you understand it, it’s so awesome.
The build blocks for RxJava are the following:
- observables representing sources of data
- subscribers (or observers) listening to the observables
Our idea was to make execution of parallel tasks in a blocking nature. We wrapped each of our sync calls inside a Single (An Observable which emits a single item, boolean in our case). Then we merged all the Singles using the Merge operator. (Combines all the observables into one, helpful for blocking it then) On the Flowable which is returned from the merge we ran `blockingGet()` which then waits until all the single tasks(observables) have completed execution.
This is how the code looks
Just this change improved our sync time from 30 * x seconds to (x + 2) to seconds.
If RxJava is working for you, then keep rocking that codebase. Don’t change a thing.
Post this change we started using RxJava everywhere in our codebase. Debounce operator while searching from a Edit text, RxBinding with MVVM etc. And our team transformed from RxJava (I have no idea how it works) → RxJava (I love this thing)
React to all the things
Reactive programming is a lot of fun and once you get started you might want to replace all the AsyncTasks/Streaming data code with RxJava.
The Operators and ReactiveExtensions page is your go to go guide. Have fun!
Follow us on twitter for regular updates. If you liked this article, please hit the Hand icon to recommend it. This will help other Medium users find it.