Going Reactive with
RxJava
JAVANTURA Zagreb – February 2016
Hrvoje Crnjak
Java Developer @ Five
@HrvojeCrnjak
FIVE
Going Reactive with RxJava
So what does it mean for the App to be
Reactive?
His Majesty
Reactive Manifesto
ReactiveApp should be …
Message-Driven
• Components communicate via asynchronous messages (errors are messages also)
Resilient
• System stays responsive in the face of failure
Elastic (Scalable)
• System stays responsive under varying workload
Responsive
• System responds in timely manner if at all possible
Or if we put it in a diagram …
Resilient
Message-Driven
Scalable
Responsive
OOP, State of the Union
Resilient
Message-Driven
Scalable
Responsive
We’ll pack Events
into Messages TheGood
TheBad
TheUgly
State and Behavior
are Joined
State is Mutated
Error Handling up to
the Client
So how does RxJava fit into
all of this?
Event-Driven → Message-Driven
Everything is a message
• Including errors
Everyone (each component) can be Producer and Consumer of
messages
Producer Consumer
Stream of
Messages
UI Component
Remote Service
Scheduled Job
Whoever’s
Subscribed
Events
Computation Result
Query Result
Making Streams of Messages with RxJava
Observable – Representation of the Message Producer
Observer – Representation of the Message Consumer
• onNext
• onCompleted
• onError
onNext
onNext
onNext
onCompleted
ObservableStream
of Messages
Making Streams of Messages with RxJava
Observable – Representation of the Message Producer
Observer – Representation of the Message Consumer
• onNext
• onCompleted
• onError
onNext
onNext
onError
ObservableStream
of Messages
Making an Observable
Predefined Observable templates
• Observable.from
• Observable.just
• Factory Methods
• Observable.interval , Observable.range , Observable.empty
Observable<Long> intervalObservable = Observable.interval(500L, TimeUnit.MILLISECODS);
Observable<Integer> rangeObservable = Observable.range(1, 10);
Observable<Character> justObservable = Observable.just('R', 'x', 'J', 'a', 'v', 'a');
List<String> list = Arrays.asList("blue", "red", "green", "yellow", "orange");
Observable<String> listObservable = Observable.from(list)
Making an Observable
The real Power lies in
• Observable.create
public static Observable<SomeDataType> getData(String someParameter) {
return Observable.create(subscriber -> {
try {
SomeDataType result = SomeService.getData(someParameter);
subscriber.onNext(result);
subscriber.onCompleted();
} catch (Exception e) {
subscriber.onError(e);
}
});
}
Consuming an Observable
At it’s Core very simple
• observableInstance.subscribe
observableInstance.subscribe(new Observer<SomeDataType>() {
@Override
public void onNext(SomeDataType message) {
// Do something on each Message received
}
@Override
public void onError(Throwable error) {
// Do something on Error
}
@Override
public void onCompleted() {
// Do something when Observable completes
}
});
Consuming an Observable
At it’s Core very simple
• observableInstance.subscribe
observableInstance.subscribe(
(SomeDataType message) -> {/*onNext*/},
(Throwable error) -> {/*onError*/},
() -> {/*onCompleted*/});
OOP + RxJava, State of the Union
Resilient
Message-Driven
Scalable
Responsive
Observer + Observable
Making the System Scalable
How to approach the problem
• Scale up – I don’t think so
• Scale out – That’s more like it
• A lot of Cores and Memory!
Desired Characteristics of our System
• Program logic should execute in Parallel
• Data immutability is Allowed/Encouraged
The answer
• Functional programming
Making the System Scalable
Why FP Approach
• State HandledTransparently
• Highly composable
When we apply this to Rx world …
• Data manipulation
• Composable FP style Observable methods
• State change
• Each change of state will be a new message in the Stream
Composable methods with RxJava
There are methods for
• Content filtering
• Time filtering
• Data transformation
• Stream composition
observableInstance.filter(element -> element < 10)
observableInstance.timeout(100, TimeUnit.MILLISECONDS)
observableInstance.map(number -> number * number)
Observable<String> mergedObservable = Observable
.merge(firstObservable, secondObservable, thirdObservable);
Manipulating Streams with RxJava
1Observable.range(1,9) 2 3 4 5 6 7 8 9
5 6 7 8 9
.skipWhile(element -> element < 5)
5 6 7
.take(3)
18
.reduce((elem1, elem2) -> elem1 + elem2)
.subscribe(result -> /*do something*/)
OOP + RxJava, State of the Union
Observer + Observable
Resilient
Message-Driven
Scalable
Responsive
Observable
Methods (FP style)
+
Transparent State
WHEN the System Fails
With classic OOP the Client has to
• try/catch
• Resource cleanup
With RxJava the Client has to
• onError
• Error is a First-class Citizen
onNext
onNext
onError
ObservableStream
of Messages
Recovering from Errors
When the Error Occurs
• Observable finishes
• Observer’s recovery options
• onErrorReturn , onErrorResumeNext, retry
mainObservable.onErrorReturn(throwable -> {
System.out.println("The original feed failed with" + throwable);
return oneMoreMessage;
}).subscribe(data -> {/* doSomething */});
mainObservable.onErrorResumeNext(throwable -> {
System.out.println("The original feed failed with" + throwable);
return backupObservable;
}).subscribe(data -> {/* doSomething */});
OOP + RxJava, State of the Union
Observer + Observable
Error is a First-
Class Citizen
Resilient
Message-Driven
Scalable
Responsive
Observable
Methods (FP style)
+
Transparent State
Let’s Get ResponsiVle
Responsive
• To Our Client
• Already improved Scalability and Resilience
• Asynchronous execution
Responsible
• To Our System (to our Resources)
Asynchronous Streams
“Out of the Box”
main
Main thread
Stack
Asynchronous Streams
“Out of the Box”
main
Main thread
Stack
observable.subscribe
(onNext, onCompleted)
Asynchronous Streams
“Out of the Box”
main
Main thread
Stack
observable.subscribe
(onNext, onCompleted)
observable.subscribe
remoteService.getData()
Asynchronous Streams
“Out of the Box”
main
Main thread
Stack
observable.subscribe
(onNext, onCompleted)
observable.subscribe
remoteService.getData()
remoteService.getData
Asynchronous Streams
“Out of the Box”
main
Main thread
Stack
observable.subscribe
(onNext, onCompleted)
observable.subscribe
remoteService.getData()
subscriber.onNext(data)
Asynchronous Streams
“Out of the Box”
main
Main thread
Stack
observable.subscribe
(onNext, onCompleted)
observable.subscribe
remoteService.getData()
subscriber.onNext(data)
subscriber.onNext
Asynchronous Streams
“Out of the Box”
main
Main thread
Stack
observable.subscribe
(onNext, onCompleted)
observable.subscribe
remoteService.getData()
subscriber.onNext(data)
subscriber.onCompleted()
Asynchronous Streams
“Out of the Box”
main
Main thread
Stack
observable.subscribe
(onNext, onCompleted)
observable.subscribe
remoteService.getData()
subscriber.onNext(data)
subscriber.onCompleted()
subscriber.onCompleted
Asynchronous Streams
“Out of the Box”
main
Main thread
Stack
observable.subscribe
(onNext, onCompleted)
observable.subscribe
remoteService.getData()
subscriber.onNext(data)
subscriber.onCompleted()
Asynchronous Streams
“Out of the Box”
main
Main thread
Stack
observable.subscribe
(onNext, onCompleted)
remoteService.getData()
subscriber.onNext(data)
subscriber.onCompleted()
Asynchronous Streams
“Out of the Box”
Main thread
Stack empty
observable.subscribe
(onNext, onCompleted)
remoteService.getData()
subscriber.onNext(data)
subscriber.onCompleted()
Asynchronous Streams
Let’s get Asynchronous
• Thread handling with Observable
• subscribeOn(Scheduler) -Thread Observable will run on
• observeOn(Scheduler) -Thread Observer will run on
• Available Schedulers
• immediate – use CallerThread
• newThread – do work on newThread
• trampoline – enqueue work on CallerThread
• io – Thread pool used for IO tasks
• computation – Thread pool used for Computation tasks
Asynchronous Streams
Asynchronous in practice
Main thread
Asynchronous Streams
Asynchronous in practice
Main thread
observable
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.computation())
.subscribe(onNext, onCompleted)
Asynchronous Streams
Asynchronous in practice
Main thread
observable
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.computation())
.subscribe(onNext, onCompleted)
IOthread
remoteService.getData()
subscriber.onNext(data)
Asynchronous Streams
Asynchronous in practice
Main thread
observable
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.computation())
.subscribe(onNext, onCompleted)
IOthread
remoteService.getData()
subscriber.onNext(data)
Computation
thread
Asynchronous Streams
Asynchronous in practice
Main thread
observable
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.computation())
.subscribe(onNext, onCompleted)
IOthread
remoteService.getData()
subscriber.onNext(data)
subscriber.onCompleted()
Computation
thread
Responsible Client
Being Reactive isn’t just about doing something fast,
it’s about not doing it at all.
Or to be more precise, to do only what’s necessary.
Responsible Client
Being Responsible
• Observable works only when someone’s listening
• subscribe triggers Observable Stream
• Client (Consumer of Stream) tells us when he’s done listening
• unsubscribe
Responsible Client
Two flavors of Unsubscribing
• Client (Consumer) is unsubscribed from “outside”
Subscription subscription = observableInstance.subscribe(
(Long message) -> {/*onNext*/},
(Throwable error) -> {/*onError*/},
() -> {/*onCompleted*/});
// Do some logic;
subscription.unsubscribe();
Responsible Client
Two flavors of Unsubscribing
• Client (Consumer) is unsubscribed from “inside”
observableInstance.subscribe(new Subscriber<Long>() {
@Override
public void onNext(Long message) {
// Do something on each Message received
unsubscribe();
}
@Override
public void onError(Throwable e) {
// Do something on Error
}
@Override
public void onCompleted() {
// Do something when Observable completes
}
});
OOP + RxJava, State of the Union
Observer + Observable
Error is a First-
Class Citizen
Asynchronous +
Resources on Demand
Message-Driven
Scalable
Responsive
Resilient
Observable
Methods (FP style)
+
Transparent State
Thanks for your time!
Q & hopefully A

Javantura v3 - Going Reactive with RxJava – Hrvoje Crnjak

  • 1.
    Going Reactive with RxJava JAVANTURAZagreb – February 2016 Hrvoje Crnjak Java Developer @ Five @HrvojeCrnjak FIVE
  • 2.
  • 3.
    So what doesit mean for the App to be Reactive? His Majesty Reactive Manifesto
  • 4.
    ReactiveApp should be… Message-Driven • Components communicate via asynchronous messages (errors are messages also) Resilient • System stays responsive in the face of failure Elastic (Scalable) • System stays responsive under varying workload Responsive • System responds in timely manner if at all possible
  • 5.
    Or if weput it in a diagram … Resilient Message-Driven Scalable Responsive
  • 6.
    OOP, State ofthe Union Resilient Message-Driven Scalable Responsive We’ll pack Events into Messages TheGood TheBad TheUgly State and Behavior are Joined State is Mutated Error Handling up to the Client
  • 7.
    So how doesRxJava fit into all of this?
  • 8.
    Event-Driven → Message-Driven Everythingis a message • Including errors Everyone (each component) can be Producer and Consumer of messages Producer Consumer Stream of Messages UI Component Remote Service Scheduled Job Whoever’s Subscribed Events Computation Result Query Result
  • 9.
    Making Streams ofMessages with RxJava Observable – Representation of the Message Producer Observer – Representation of the Message Consumer • onNext • onCompleted • onError onNext onNext onNext onCompleted ObservableStream of Messages
  • 10.
    Making Streams ofMessages with RxJava Observable – Representation of the Message Producer Observer – Representation of the Message Consumer • onNext • onCompleted • onError onNext onNext onError ObservableStream of Messages
  • 11.
    Making an Observable PredefinedObservable templates • Observable.from • Observable.just • Factory Methods • Observable.interval , Observable.range , Observable.empty Observable<Long> intervalObservable = Observable.interval(500L, TimeUnit.MILLISECODS); Observable<Integer> rangeObservable = Observable.range(1, 10); Observable<Character> justObservable = Observable.just('R', 'x', 'J', 'a', 'v', 'a'); List<String> list = Arrays.asList("blue", "red", "green", "yellow", "orange"); Observable<String> listObservable = Observable.from(list)
  • 12.
    Making an Observable Thereal Power lies in • Observable.create public static Observable<SomeDataType> getData(String someParameter) { return Observable.create(subscriber -> { try { SomeDataType result = SomeService.getData(someParameter); subscriber.onNext(result); subscriber.onCompleted(); } catch (Exception e) { subscriber.onError(e); } }); }
  • 13.
    Consuming an Observable Atit’s Core very simple • observableInstance.subscribe observableInstance.subscribe(new Observer<SomeDataType>() { @Override public void onNext(SomeDataType message) { // Do something on each Message received } @Override public void onError(Throwable error) { // Do something on Error } @Override public void onCompleted() { // Do something when Observable completes } });
  • 14.
    Consuming an Observable Atit’s Core very simple • observableInstance.subscribe observableInstance.subscribe( (SomeDataType message) -> {/*onNext*/}, (Throwable error) -> {/*onError*/}, () -> {/*onCompleted*/});
  • 15.
    OOP + RxJava,State of the Union Resilient Message-Driven Scalable Responsive Observer + Observable
  • 16.
    Making the SystemScalable How to approach the problem • Scale up – I don’t think so • Scale out – That’s more like it • A lot of Cores and Memory! Desired Characteristics of our System • Program logic should execute in Parallel • Data immutability is Allowed/Encouraged The answer • Functional programming
  • 17.
    Making the SystemScalable Why FP Approach • State HandledTransparently • Highly composable When we apply this to Rx world … • Data manipulation • Composable FP style Observable methods • State change • Each change of state will be a new message in the Stream
  • 18.
    Composable methods withRxJava There are methods for • Content filtering • Time filtering • Data transformation • Stream composition observableInstance.filter(element -> element < 10) observableInstance.timeout(100, TimeUnit.MILLISECONDS) observableInstance.map(number -> number * number) Observable<String> mergedObservable = Observable .merge(firstObservable, secondObservable, thirdObservable);
  • 19.
    Manipulating Streams withRxJava 1Observable.range(1,9) 2 3 4 5 6 7 8 9 5 6 7 8 9 .skipWhile(element -> element < 5) 5 6 7 .take(3) 18 .reduce((elem1, elem2) -> elem1 + elem2) .subscribe(result -> /*do something*/)
  • 20.
    OOP + RxJava,State of the Union Observer + Observable Resilient Message-Driven Scalable Responsive Observable Methods (FP style) + Transparent State
  • 21.
    WHEN the SystemFails With classic OOP the Client has to • try/catch • Resource cleanup With RxJava the Client has to • onError • Error is a First-class Citizen onNext onNext onError ObservableStream of Messages
  • 22.
    Recovering from Errors Whenthe Error Occurs • Observable finishes • Observer’s recovery options • onErrorReturn , onErrorResumeNext, retry mainObservable.onErrorReturn(throwable -> { System.out.println("The original feed failed with" + throwable); return oneMoreMessage; }).subscribe(data -> {/* doSomething */}); mainObservable.onErrorResumeNext(throwable -> { System.out.println("The original feed failed with" + throwable); return backupObservable; }).subscribe(data -> {/* doSomething */});
  • 23.
    OOP + RxJava,State of the Union Observer + Observable Error is a First- Class Citizen Resilient Message-Driven Scalable Responsive Observable Methods (FP style) + Transparent State
  • 24.
    Let’s Get ResponsiVle Responsive •To Our Client • Already improved Scalability and Resilience • Asynchronous execution Responsible • To Our System (to our Resources)
  • 25.
    Asynchronous Streams “Out ofthe Box” main Main thread Stack
  • 26.
    Asynchronous Streams “Out ofthe Box” main Main thread Stack observable.subscribe (onNext, onCompleted)
  • 27.
    Asynchronous Streams “Out ofthe Box” main Main thread Stack observable.subscribe (onNext, onCompleted) observable.subscribe remoteService.getData()
  • 28.
    Asynchronous Streams “Out ofthe Box” main Main thread Stack observable.subscribe (onNext, onCompleted) observable.subscribe remoteService.getData() remoteService.getData
  • 29.
    Asynchronous Streams “Out ofthe Box” main Main thread Stack observable.subscribe (onNext, onCompleted) observable.subscribe remoteService.getData() subscriber.onNext(data)
  • 30.
    Asynchronous Streams “Out ofthe Box” main Main thread Stack observable.subscribe (onNext, onCompleted) observable.subscribe remoteService.getData() subscriber.onNext(data) subscriber.onNext
  • 31.
    Asynchronous Streams “Out ofthe Box” main Main thread Stack observable.subscribe (onNext, onCompleted) observable.subscribe remoteService.getData() subscriber.onNext(data) subscriber.onCompleted()
  • 32.
    Asynchronous Streams “Out ofthe Box” main Main thread Stack observable.subscribe (onNext, onCompleted) observable.subscribe remoteService.getData() subscriber.onNext(data) subscriber.onCompleted() subscriber.onCompleted
  • 33.
    Asynchronous Streams “Out ofthe Box” main Main thread Stack observable.subscribe (onNext, onCompleted) observable.subscribe remoteService.getData() subscriber.onNext(data) subscriber.onCompleted()
  • 34.
    Asynchronous Streams “Out ofthe Box” main Main thread Stack observable.subscribe (onNext, onCompleted) remoteService.getData() subscriber.onNext(data) subscriber.onCompleted()
  • 35.
    Asynchronous Streams “Out ofthe Box” Main thread Stack empty observable.subscribe (onNext, onCompleted) remoteService.getData() subscriber.onNext(data) subscriber.onCompleted()
  • 36.
    Asynchronous Streams Let’s getAsynchronous • Thread handling with Observable • subscribeOn(Scheduler) -Thread Observable will run on • observeOn(Scheduler) -Thread Observer will run on • Available Schedulers • immediate – use CallerThread • newThread – do work on newThread • trampoline – enqueue work on CallerThread • io – Thread pool used for IO tasks • computation – Thread pool used for Computation tasks
  • 37.
  • 38.
    Asynchronous Streams Asynchronous inpractice Main thread observable .subscribeOn(Schedulers.io()) .observeOn(Schedulers.computation()) .subscribe(onNext, onCompleted)
  • 39.
    Asynchronous Streams Asynchronous inpractice Main thread observable .subscribeOn(Schedulers.io()) .observeOn(Schedulers.computation()) .subscribe(onNext, onCompleted) IOthread remoteService.getData() subscriber.onNext(data)
  • 40.
    Asynchronous Streams Asynchronous inpractice Main thread observable .subscribeOn(Schedulers.io()) .observeOn(Schedulers.computation()) .subscribe(onNext, onCompleted) IOthread remoteService.getData() subscriber.onNext(data) Computation thread
  • 41.
    Asynchronous Streams Asynchronous inpractice Main thread observable .subscribeOn(Schedulers.io()) .observeOn(Schedulers.computation()) .subscribe(onNext, onCompleted) IOthread remoteService.getData() subscriber.onNext(data) subscriber.onCompleted() Computation thread
  • 42.
    Responsible Client Being Reactiveisn’t just about doing something fast, it’s about not doing it at all. Or to be more precise, to do only what’s necessary.
  • 43.
    Responsible Client Being Responsible •Observable works only when someone’s listening • subscribe triggers Observable Stream • Client (Consumer of Stream) tells us when he’s done listening • unsubscribe
  • 44.
    Responsible Client Two flavorsof Unsubscribing • Client (Consumer) is unsubscribed from “outside” Subscription subscription = observableInstance.subscribe( (Long message) -> {/*onNext*/}, (Throwable error) -> {/*onError*/}, () -> {/*onCompleted*/}); // Do some logic; subscription.unsubscribe();
  • 45.
    Responsible Client Two flavorsof Unsubscribing • Client (Consumer) is unsubscribed from “inside” observableInstance.subscribe(new Subscriber<Long>() { @Override public void onNext(Long message) { // Do something on each Message received unsubscribe(); } @Override public void onError(Throwable e) { // Do something on Error } @Override public void onCompleted() { // Do something when Observable completes } });
  • 46.
    OOP + RxJava,State of the Union Observer + Observable Error is a First- Class Citizen Asynchronous + Resources on Demand Message-Driven Scalable Responsive Resilient Observable Methods (FP style) + Transparent State
  • 47.
    Thanks for yourtime! Q & hopefully A

Editor's Notes

  • #4 Now, in this lecture I won’t try to force some vague definition on you. If you want that, go to a wiki page and read it there What I will do he is I’ll state my case of what RxJava is good for, what are RxJava’s features and you can make your own definition of what RxJava is Java, JS, Scala, Clojure, Swift Reactive Programming raises the level of abstraction of your code so you can focus on the interdependence of events that define the business logic, rather than having to constantly fiddle with a large amount of implementation details. Code in RP will likely be more concise. The benefit is more evident in modern webapps and mobile apps that are highly interactive with a multitude of UI events related to data events. 10 years ago, interaction with web pages was basically about submitting a long form to the backend and performing simple rendering to the frontend. Apps have evolved to be more real-time: modifying a single form field can automatically trigger a save to the backend, "likes" to some content can be reflected in real time to other connected users, and so forth. Apps nowadays have an abundancy of real-time events of every kind that enable a highly interactive experience to the user. We need tools for properly dealing with that, and Reactive Programming is an answer. Rx works great for event-heavy frontends and apps. But it is not just a client-side thing, it works great also in the backend and close to databases. In fact, RxJava is a key component for enabling server-side concurrency in Netflix's API. Rx is not a framework restricted to one specific type of application or language. It really is a paradigm that you can use when programming any event-driven software.
  • #5 NAGLASITI DA SU SVE APLIKACIJE REAKTIVNE!!!!!!!!!!!!!!!!!! ZAHER
  • #6 Reactive = Responsive
  • #7 Responsive – cornerstone of usability and utility, requires rapid detection of errors and quick responses, requires predictable response times and quality of service, requires pre-planned graceful degradation of service, awareness of time is first class Resilient – Recovers from errors (failure is a routine, the system will inevitably fail at some tome), failure is not disruptive, failure is expected, so failure is normal part of your domain model, implementation etc. Requires replication, containment, isolation and delegation, requires separation between normal control flow and error handling Replication - other copies (data and services) replaced lost copies. Containment and isolation - firewalls stop disaster from spreading. Delegation - indirection to allow new copies to step into “holes”. Elastic – Scale up and down, As demand rises and falls, you must gracefully scale up to meet increasing demand and scale down to conserve resources. Detect changing input patterns, automatically adjust services (human intervention must be minimal), scale across commodity hardware, no bottlenecks od contention points To scale down, you must be able to drain services from nodes (harder it the node holds data) Message-Driven – To react, you must be message driven (interact with the world through messages), Asynchronous message passing - It can’t be command and control. Blocking while waiting for a response fails to scale. (See Amdahl’s Law) Defines boundaries, promotes loose coupling and isolation - Clear separation between components (whether or not the messages cross process boundaries), which encourages effective decomposition into focused services that are isolated from each other and loosely coupled. Promotes location transparency – source and receiver can change, so services can be migrated to adopt to changing load dynamics Handle errors as messages - Also, you can use the same message infrastructure to communicate error scenarios as well as normal processing. Promotes global management and flow control through back pressure - Think of the messages as forming a stream. If a common implementation infrastructure is used, it’s possible to monitor and manage traffic flow. Back pressure is the idea of communication between sender and receiver to control the rate of flow. We’ll return to it.
  • #8 https://www.youtube.com/watch?v=4L3cYhfSUZs You end up with a model of your world (domain). And all of this is a big blob which is very hard to scale. Resilient – you can, and usually you must also handle errors, but OOP as a concept doesn’t enforce that on you The biggest mistake of OOP was the idea that we should faithfully model the world in code Controversial, but I believe much of our code bloat and inflexibility is actually caused by this mistaken belief. Example: Does a payroll calculator need the concepts of Pay, Deductions, etc.? Or should we just stream numbers through math logic?
  • #13 From – future, iterable, array Just – up to 10 values
  • #19 Scalability is the trait where a software solution can handle increased loads of work. This can be larger data-sets, higher request rates, combination of size and velocity etc. When talking about systems scalability, we usually differentiate between "Scale up" - the ability to grow by using stronger hardware "Scale out"- the ability to grow by adding more hardware A solution that can scale out can usually grow to lager loads in a more cost effective way. An important thing to know here is Amdahl's law that states that the ability to scale out is limited by the sequential part of the software At it’s core FP is all about transforming data No state, no higher meaning, just a bunch of functions transforming a bunch of data I know, most of you are Java developers and Java is at its core Object-oriented language, but in this case FP really is a Perfect fit If you look at it: we have streams of we can say independent messages, what else to do than put those messages through a bunch of functions that will transform/filter etc. the data and give us some meaningful result
  • #26 Functions without shared state, functions that are side effect free
  • #29 When dealing with errors in RxJava, you should be aware that they terminate the Observable chain of actions. Much like with your normal procedural code, once you are in the catch block, you can't go back to the code that has thrown the exception.
  • #32 RxJava is single-threaded by default, calling subscribe will block calling thread
  • #43 This achieves concurrency A Scheduler is an object that schedules units of work. You can find common implementations of this class in Schedulers Internally Java thread pools - RxJava-managed pool of reusable Thread instances RxJava's Observable chains seem a good match for the threads. It would be great if we could subscribe to our source and do all the transforming, combining, and filtering in the background and, when everything is done, have the result to be passed to the main threads. Yes, this sounds wonderful, but RxJava is single-threaded by default. This means that, in the most cases, when the subscribe method is called on an Observable instance, the current thread blocks until everything is emitted. In order to have multi-threaded logic, we'll have to learn just these two things: • The types of schedulers we can chose from • How to use these schedulers with an arbitrary Observable chain of operations The computation scheduler is very similar to the new thread one, but it takes into account the number of processors/cores that the machine on which it runs has, and uses a thread pool that can reuse a limited number of threads. Every new Worker instance schedules sequential actions on one of these Thread instances. If the thread is not used at the moment they are executed, and if it is active, they are enqueued to execute on it later. The Input-Output (IO) scheduler uses a ScheduledExecutorService instance to retrieve the threads from a thread pool for its workers. Unused threads are cached and reused on demand. It can spawn an arbitrary number of threads if it is necessary. The IO scheduler is reserved for blocking IO operations. Use it for requests to servers, reading from files and sockets, and other similar blocking tasks. Note that its thread pool is unbounded; if its workers are not unsubscribed, the pool will grow indefinitely. The Schedulers.from(Executor) method This can be used to create a custom Scheduler instance. If none of the predefined schedulers work for you, use this method, passing it to a java.util.concurrent. Executor instance, to implement the behavior you need.