The word "Reactive" can be confusing. As the founder of the Reactive Amsterdam meetup, I can tell there are two main topics here: Functional Reactive Programming (here with reference to Android) and "Reactive" in the sense of the Reactive Manifesto.
10. RxJava goes hand in hand with Java8’s Lambdas
new Func1<String, Integer>() {
@Override
public Integer call(String s) {
return s.length();
}
}
(String s) -> {
return s.length();
}
s -> s.length();
Retrolamba plugin for
Android < N
11. RxJava: dealing with a stream of items
class Cat {
...
public String getName()
public Color getColor()
public Picture fetchPicture()
...
}
12. RxJava: dealing with a stream of items
Observable.from(myCats);
cat -> Timber.d(cat.getName())
List<Cat> myCats;
Observable obs =
obs.subscribe( );
Observable.from(myCats)
.subscribe(cat -> Timber.d(cat.getName()));
13. RxJava: work on the stream
Observable.from(myCats)
.subscribe(color -> Timber.d(color));
map: function that takes T => outputs R
.map( )cat -> cat.getColor()
14. RxJava: operators to manipulate the stream
Observable.from(myCats)
.distinct()
.delay(2, TimeUnit.SECONDS)
.filter(cat -> cat.getColor().isWhite())
.map(cat -> cat.getName())
.subscribe(name ->
Timber.d(“a unique, delayed white cat called ” + name));
18. RxJava: other ways of creating Observables
// emits on single item and completes
Observable.just
// emits one item after a certain delay
Observable.timer
// emits a series of integers at regular pace
Observable.interval
.. plus many others, and you can create your own
— BUT TRY NOT TO -
19. RxJava: a few disadvantages
• debugging is more difficult
• methods with side effects
• powerful abstraction - lot of stuff under the hood
20. RxJava: demo with Retrofit & Meetup Streams
http://stream.meetup.com/2/rsvp
Meetup Streaming API
25. RxJava: demo with Meetup Streams
https://github.com/ticofab/android-meetup-streams
26. 2006 2016
Servers ~10 The sky is the limit.
Response time seconds milliseconds
Offline maintenance hours what?
Data amount Gigabytes Petabytes
Machines Single core, little distribution
Must work across async
boundaries (location, threads)
Kind of data Request - response Streams (endless)
Reactive in the sense of the Reactive Manifesto
28. The Reactive traits
A reactive computer system must Trait
React to its users Responsive
React to failure and stay available Resilient
React to varying load conditions Elastic
Its components must react to inputs Message-driven
29. Reactive traits: Responsive
• A human who visits a website
• A client which makes a request to a server
• A consumer which contacts a provider
• . . .
A Reactive system responds to inputs and usage from its user.
30. Reactive traits: Elastic
• Scale OUT and IN: use just the right amount
• Elasticity relies on distribution
• Ensure replication in case of failure
Scale on demand to react to varying load
35. Reactive Pattern: Simple Component Pattern
“One component should do only one thing but do it in full. The aim is to
maximise cohesion and minimise coupling between components.”
36. Reactive Pattern: Simple Component Pattern
Actor 1
Actor 3
Actor 2
• contains state
• has a mailbox to receive
and send messages
• contains behaviour logic
• has a supervisor
Actor model Supervisor
37. Example: Synchronous DB access
Activity DB service DB
List<Cat> cats = new ArrayList<Cat>();
try {
cats = dbService.getAllCats();
} catch (ExampleException e) {
// TODO
}
38. Example: DB access with callback
dbService.getAllCats(new OnCompleted() {
@Override
public void onDataRetrieved(List<Cat> cats) {
// TODO
}
});
Activity DB service DB
40. Example: Async Messaging with Actors - messages
// message to ask for cats
public class GetCats {
}
// message to send results back
public class Results {
ArrayList<Cat> mCats;
public Results(ArrayList<Cat> cats) {
mCats = cats;
}
}
41. Example: Async Messaging with Actors - behaviour
// db actor pseudocode
@Override
public void onReceive(Message message) {
}
if (message is GetCats) {
}
// retrieve cats from database
c = contentResolver.query(...)
...
// send cats to the Activity
Results result = new Results(cats);
activityAddress.tell(result)
42. Reactive Patterns: Let it crash!
"Prefer a full component restart to complex internal failure handling".
• failure conditions WILL occur
• they might be rare and hard to reproduce
• it is much better to start clean than to try to recover
• …which might be expensive and difficult!
43. Reactive Patterns: Let it crash!
Actor supervision example
Actor 1
Actor 2
Supervisor
WhateverException!
X
Fix or
Restart
I work both as an Android and Scala engineer. I mostly use scala for backend applications. Those are a few of the companies that I worked for over the past few years. Some time ago, I got so fascinated by this Reactive concept that …
The Reactive principles are cross-technology and cross-domain, so I basically started this meetup..
If we look up “Reactive” in the vocabulary, it is an adjective meaning [READ]
Upon mentioning this word to people in technology, this word somehow comes across as confusing. I think the root is that it can be used in (at least) two context:
The paradigm is more supportive of reasoning about problems in concurrent and parallelized applications.
At its core, functional programming encourages the use of pure functions, that is a function that returns the same value every time when passed the same inputs and without side effects.
Side effects are operations inside a function that act on things outside a function. Maybe modifying some state, or inserting data in the storage. Functions with no side effects are easier to reason about, especially in complex systems.
Immutability: mutable state can be dangerous and therefore state mutation should be confined as much as possible.
Higher order functions - in functional languages, functions can exist as first-class citizens. Meaning that a function can be passed around into another function. This makes the code more composable.
Func1 is an implementation of an interface, with a method “call” that takes a string as a parameter and returns its length. Using lambdas, we can rewrite it as… and because the body of the method has a single instruction we can further simplify it like this.
In the coming examples we will use this simple object: a cat with a name, a color and whose picture we can fetch from some server online.
The Observable class in RxJava has a “from” static method that takes a collection as an input and will output its items one by one. This is called an “Observable”: a stream of data. In our case, a stream of cats.
In order to do something with these items, we need to subscribe through the subscribe function. The subscribe function takes as a parameter the implementation of an interface which takes a cat as an input and does something with it. And it’s usually chained.
You might be wondering “if I want to do something with each cat, I can do it in a classic for-loop”. This is true for these simple examples, but the beauty of RxJava is that it allows you to manipulate the stream without breaking it, and late we’ll see even more reasons.
In this example we use the map operator from RxJava. This operator lets you change the item that gets propagated through the stream. The map operator takes another function whose return type can be different than the input type. In this case we take a cat and return a color. The subscribe at the end now has a color as input.
Because a stream is potentially endless, at some point you might want to unsubscribe. The subscribe function actually returns a Subscription. We can use this subscription later to unsubscribe from the stream.
In the beginning we mentioned that RxJava makes threading easy, so let’s look at how that works.
…and you can even create your own, which can be difficult to get right but it’s a lot of fun.
So, in my experience, using RxJava in Android leads to cleaner and more maintainable code plus it’s actually fun! But there are also disadvantages…
..if we want to use this in an Android app,
The FlatMap operator that you see on the second line is similar to map: it takes an input (in this case the response body of the request) but instead of returning another type, it returns an observable of another type. Basically the “events” function takes the responseBody as input, parses the chunks into separate events and emits them as they come. And this will be the observable that we subscribe to at the end.
[END] this has come in response to the evolution of internet usage:
As the user base of web services grew, different frameworks and tools came along. The one we’ll be talking about here is the Reactive Manifesto, which defines a sort of design guideline to build reactive systems: it describes a few traits that a system should have in order to be reactive. What are the traits of reactive systems?
These traits are somehow interconnected. Now, if we look at these traits one by one…
The load of a system can change over days, weeks or part of the year. Online store have Christmas or black friday sales. Banks might have payday and such. Elasticity means that you are able to use "just the right amount" of resources for the task.
To ease out the distribution of a system, its component must be loosely coupled.
It is defined as the ability of something to jump back into shape after a failure. Resilience means to restore functionality into FULL CAPACITY, and not just crawl on. We want to heal fully. Get hit - survive and keep going: this is FAULT TOLERANCE. The problem with this is that it isn't a sustainable strategy. What we need is RESILIENCE. Resilience goes beyond fault tolerance.
One thing that we'll encounter when designing these systems, is that we'll concentrate on Messages. If only messages are exchanged between components, we have achieved separation and error containment. Focus shifts from class diagrams and interface definitions to message flow: the protocol that defines the conversation between components. Who says what at what time.
The idea is that each component doesn’t share its internal state. In the real world, we don't read in each other's brains. Not yet at least. We use communication.
An actor is an isolated component that contains State, Behavior, a Mailbox, Children and a Supervisor.
The supervisor is especially important for error containment and resilience.
In a typical Java app you would see something like this. What you need to do here is run this code in a separate thread.
Maybe getAllCats() could take a callback. In this case, we need some additional mechanism to signal failures, and the threading is a bit mysterious, plus callbacks can end up in the mythical callback hell
In a typical Java app you would see something like this. What you need to do here is run this code in a separate thread.Maybe getAllCats() could take a callback
… the activity will also have a similar method that receives a Result message and does something with it.
.. recovery which might be more expensive: catch exceptions, store statistics etc. The goal of the restart is to wipe all the state that the component has grown into. Trying to recover from sketchy states can be tricky and generate even more mess.
Decoupling and failure containment is really important as it enables supervision and actor could be restarted by the supervisor. Failure WILL happen, so fault-avoidance is doomed. The only thing we can do is embrace failure and gracefully deal with the consequences.
I reckon you might be more confused than when I started. That’s possibly a good thing.