Reactive in Android & beyond Rx
Fabio Tiriticco / @ticofab
DAUG Meetup 23 August 2016
A little info about myself
AndroidEngineerBackendArchitect
The Reactive Amsterdam meetup
Reactive Amsterdam
• cross-technology• cross-domain
“Reactive” in the vocabulary
Reactive (adjective):
Tending to act in response to an agent or influence
Reactive Confusion
FunctionalReactiveProgramming
Reactiveinthecontextofthe“ReactiveManifesto”
OR
Reactive Programming
Why Functional?
Moresupportiveofreasoningaboutproblemsinconcurrentandparallelisedapplications.
• encouragesuseofpurefunctions-minimisesideeffects• encouragesimmutability-statedoesn’tgetpassedaround• higher-orderfunctions-reusabilityandcomposability
Hello, RxJava!
Mobileengineeringishardandtherearehighexpectations.
RxJavaiscoolbecause
• itmakesitsupereasytoswitchbetweenthreads• letsusdealwithdataasastream• bringsussomedegreeoffunctionalprogramming
Hello, RxJava!
RxJava
RxJs
RxClojure
RxSwift
…
• Asynchronousprogramming• Observablestreams
Opensourcelibrariesfor
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();
RetrolambapluginforAndroid<N
RxJava: dealing with a stream of items
class Cat {...public String getName()public Color getColor()public Picture fetchPicture()...
}
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()));
RxJava: work on the stream
Observable.from(myCats)
.subscribe(color -> Timber.d(color));
map: function that takes T => outputs R
.map( )cat -> cat.getColor()
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));
Observable.from(myCats).subscribe(
cat -> Timber.d(cat.getName()),error -> error.printStackTrace(),() -> Timber.d(“no more cats”)
);
RxJava: subscriber interface
Observable.from(myCats).subscribe(
onNext<T>, // next item TonError, // throwableonComplete // void
);
Observable.from(myCats) .subscribe(cat -> Timber.d(“cat”));
RxJava: unsubscribe
Subscription subs =
subs.unsubscribe();
RxJava: threading
Observable.from(myCats)
.map(cat -> cat.fetchPicture())
.map(picture -> Filter.applyFilter(picture))
.subscribe(filteredPicture -> display(filteredPicture)
);
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
RxJava: other ways of creating Observables
// emits on single item and completesObservable.just
// emits one item after a certain delayObservable.timer
// emits a series of integers at regular paceObservable.interval
.. plus many others, and you can create your own — BUT TRY NOT TO -
RxJava: a few disadvantages
• debuggingismoredifficult• methodswithsideeffects• powerfulabstraction-lotofstuffunderthehood
RxJava: demo with Retrofit & Meetup Streams
http://stream.meetup.com/2/rsvp
Meetup Streaming API
RxJava: demo with Meetup Streams
RxJava: demo with Retrofit & Meetup Streams
interface MeetupAPI { @GET("http://stream.meetup.com/2/rsvp") @Streaming Observable<ResponseBody> meetupStream();}
RxJava: demo with RSVP Meetup Streams
meetupAPI.meetupStream()....flatMap(responseBody -> events(responseBody.source())).map(string -> gson.fromJson(string, RSVP.class))... .subscribe(rsvp -> ...);
map: T => RflatMap: T => Observable<R>
RxJava: demo with Meetup Streams
RxJava: demo with Meetup Streams
https://github.com/ticofab/android-meetup-streams
2006 2016
Servers ~10 Theskyisthelimit.
Responsetime seconds milliseconds
Offlinemaintenance hours what?
Dataamount Gigabytes Petabytes
Machines Singlecore,littledistribution Mustworkacrossasyncboundaries(location,threads)
Kindofdata Request-response Streams(endless)
Reactive in the sense of the Reactive Manifesto
Evolution of internet usage
The Reactive traits
Areactivecomputersystemmust Trait
Reacttoitsusers Responsive
Reacttofailureandstayavailable Resilient
Reacttovaryingloadconditions Elastic
Itscomponentsmustreacttoinputs Message-driven
Reactive traits: Responsive
• Ahumanwhovisitsawebsite• Aclientwhichmakesarequesttoaserver• Aconsumerwhichcontactsaprovider• ...
AReactivesystemrespondstoinputsandusagefromitsuser.
Reactive traits: Elastic
• ScaleOUTandIN:usejusttherightamount• Elasticityreliesondistribution• Ensurereplicationincaseoffailure
Scaleondemandtoreacttovaryingload
Reactive traits: Resilient
Itdoesn'tmatterhowgreatyourapplicationisifitdoesn'twork.
FAULTTOLERANCE RESILIENCEVS
Reactive traits: Message Driven
ReactivesystemsdesignconcentratesonMessages.
Asynchronousmessagingenables:
• Separationbetweencomponents• Errorcontainment-avoidchainfailures• Domainmappingclosertoreality
The Reactive Manifesto
Reactive Patterns
DesignpatternstoachieveReactiveprinciples.
Toolkitsexisttoimplementthesepatterns.
Reactive Pattern: Simple Component Pattern
“Onecomponentshoulddoonlyonethingbutdoitinfull.Theaimistomaximisecohesionandminimisecouplingbetweencomponents.”
Reactive Pattern: Simple Component Pattern
Actor1
Actor3
Actor2
• containsstate• hasamailboxtoreceiveandsendmessages
• containsbehaviourlogic• hasasupervisor
ActormodelSupervisor
Example: Synchronous DB access
Activity DBservice DB
List<Cat> cats = new ArrayList<Cat>();try {
cats = dbService.getAllCats();} catch (ExampleException e) {
// TODO}
Example: DB access with callback
dbService.getAllCats(new OnCompleted() {@Overridepublic void onDataRetrieved(List<Cat> cats) {
// TODO}
});
Activity DBservice DB
Example: Async Messaging with Actors
Activityactor DBActor DB
Example: Async Messaging with Actors - messages
// message to ask for catspublic class GetCats {}
// message to send results backpublic class Results {
ArrayList<Cat> mCats;public Results(ArrayList<Cat> cats) {
mCats = cats;}
}
Example: Async Messaging with Actors - behaviour
// db actor pseudocode@Overridepublic void onReceive(Message message) {
}
if (message is GetCats) {
}
// retrieve cats from databasec = contentResolver.query(...)...// send cats to the ActivityResults result = new Results(cats);activityAddress.tell(result)
Reactive Patterns: Let it crash!
"Preferafullcomponentrestarttocomplexinternalfailurehandling".
• failureconditionsWILLoccur• theymightberareandhardtoreproduce• itismuchbettertostartcleanthantotrytorecover• …whichmightbeexpensiveanddifficult!
Reactive Patterns: Let it crash!
Actorsupervisionexample
Actor1
Actor2
Supervisor
WhateverException!
X
FixorRestart
Reactive Patterns: Let it crash!
• themachineonlyacceptsexactchange
Reactive Patterns: Let it crash!
Scenario1:Theuserinsertswrongamountofcoins
X
Error
Reactive Patterns: Let it crash!
Scenario2:Themachineisoutofcoffeebeans
Failure(!=error)
Reactive Patterns: Let it crash!
Recap
• TriedtoclarifytheReactiveConfusion• ExamplesofFRPinAndroid• ReactiveprinciplesfromtheReactiveManifesto• AcoupleofDesignPatternstoachievethem• (withaglimpseofpseudoimplementation)
Reactive Amsterdam
Thanks!
@ticofab
All pictures belong to their respective authors
AMSTERDAM 11-12 MAY 2016
Resources
https://github.com/ReactiveX/RxJava/wiki RxJavadocumentation&wiki
http://rxmarbles.com RxJavaoperatorsexplainedvisually
http://www.reactivemanifesto.org Thereactivemanifesto
https://www.youtube.com/watch?v=fNEZtx1VVAkhttps://www.youtube.com/watch?v=ryIAibBibQIhttps://www.youtube.com/watch?v=JvbUF33sKf8
TheReactiveRevealedseries:awesomewebinarsbythecreatorsoftheReactiveManifesto.
https://www.manning.com/books/reactive-design-patternshttps://www.youtube.com/watch?v=nSfXcSWq0ug Reactivedesignpatterns,bookandwebinar.