Reactive programming principles

684 views
577 views

Published on

A very introductive presentation about reactive programming principles. Starting from synchronous standard programming, I try to present the needs that driven to reactive programming. Callbacks, Future, Promises, Observables and Actor model are the main issues. I also make an introduction to the Reactive Manifesto.

The presentation is took from the Software Engineering course I run in the bachelor-level informatics curriculum at the University of Padova.

Published in: Software
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
684
On SlideShare
0
From Embeds
0
Number of Embeds
19
Actions
Shares
0
Downloads
15
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Reactive programming principles

  1. 1. PRINCIPI DI REACTIVE PROGRAMMING INGEGNERIA DEL SOFTWARE Università degli Studi di Padova Dipartimento di Matematica Corso di Laurea in Informatica, A.A. 2013 – 2014 rcardin@math.unipd.it
  2. 2. Ingegneria del software mod. B GO REACTIVE!  Applicazione anni 2000  Decine di server  Tempi di risposta nell’ordine dei secondi  Ore di downtime per manutenzione  Dati nell’ordine dei Gigabyte  Accedute da dispositivi desktop  Applicazione moderne (≥ 2010)  Cluster di migliaia di processi multicore  Tempi di risposta nell’ordine dei millisec  100% uptime  Dati nell’ordine dei Petabyte  Accedute da qualsiasi tipo di dispositivo 2 Riccardo Cardin
  3. 3. Ingegneria del software mod. B GO REACTIVE!  Nuovi requisiti richiedono nuove tecnologie  Reactive Application  Orientate agli eventi  Scalabili  Resilienti  Responsive 3 Riccardo Cardin "Readily responsive to a stimulus" Merriam-Webster react to events La natura event-driven abilita alle altre qualità react to load La scalabilità non deve dipendere da risorse condivise react to failure Sistemi resilienti permettono di recuperare errori a tutti i livelli react to users I tempi di risposta non devono dipendere dal carico di lavoro
  4. 4. Ingegneria del software mod. B REACTIVE MANIFESTO 4 Riccardo Cardin responsive scalable resilient event-driven • Loosely coupled design • Communication orientation • Uso efficiente delle risorse • Nessun redesing per ottenere la scalabilità • Scalabilità on-demand • Risk-management • Downtime è perdita di denaro • Parte del design • Real-time, engaging, reach, collaborative • Nessuna latenza nelle risposte
  5. 5. Ingegneria del software mod. B MODELLO SINCRONO  Il mondo sincrono è senza futuro...  Frequenti operazioni di I/O  Scarso utilizzo delle feature offerte dai processori moderni  Larga diffusione delle architetture multiprocessore  Cicli non ottimizzati  Scarso parallelismo o gestione difficoltosa  Tipico dei linguaggi imperativi e ad oggetti  C, C++, Java, ... 5 Riccardo Cardin // Synchronous world (w/o Future) val session = socialNetwork.createSessionFor("user", credentials) // blocked on method, waiting for results (latency)... session.getFriends() // There are a lot of operation to do!!! :(
  6. 6. Ingegneria del software mod. B MODELLO SINCRONO  Il mondo sincrono è senza futuro...  Esempio: recuperare il nome del file più pesante 6 Riccardo Cardin public String getBiggestFile(final File folder) { long maxLength = 0L; String fileName = null; for (final File fileEntry : folder.listFiles()) { if (maxLength < fileEntry.length()) { // Not so efficient fileName = fileEntry.getName(); maxLength = fileEntry.length(); } } return fileName ; } ... if (maxLength… // computationfileEntry.length() // I/O CPU poco utilizzata, I/O sovrabbondante Java Tempo totale di attesa
  7. 7. Ingegneria del software mod. B MODELLO ASINCRONO  Callbacks  Funzioni da invocare al termine di una elaborazione  Gestione migliore della CPU  Ridotti tempi di attesa  Più processi gestiscono più richieste  Asynchronous JavaScript and XML (AJAX) 7 Riccardo Cardin var callback = function(){ alert('I was called back asynchronously'); }; $.ajax({ type: 'GET', url: 'http://example.com', done: callback, // positive case fail: anotherCallback // negative case }); jQuery In attesa della risposta, è possibile continuare l’elaborazione (rendering UI)
  8. 8. Ingegneria del software mod. B MODELLO ASINCRONO  Callbacks  Linguaggi o framework che gestiscano l’elaborazione asincrona e concorrente  Node.js, jQuery, ...  Ma...c’è sempre un ma... 8 Riccardo Cardin CPU1 CPU2 CPU3 CPU4 Tempo totale di attesa I/O è ancora presente, ma viene distribuito sull’elaborazione di più CPU
  9. 9. Ingegneria del software mod. B MODELLO ASINCRONO  Callbacks...HELL!!! 9 Riccardo Cardin
  10. 10. Ingegneria del software mod. B 10 Riccardo Cardin module.exports = function (dir, cb) { fs.readdir(dir, function (er, files) { if (er) return cb(er) var counter = files.length var errored = false var stats = [] files.forEach(function (file, index) { fs.stat(path.join(dir,file), function (er, stat) { if (errored) return if (er) { errored = true return cb(er) } stats[index] = stat if (--counter == 0) { var largest = stats .filter(function (stat) { return stat.isFile() }) .reduce(function (prev, next) { // [6] if (prev.size > next.size) return prev return next }) cb(null, files[stats.indexOf(largest)]) } }) // [1] }) // [2] }) // [3] } node.js Innesto callback per gestire i flussi degli eventi Difficile da verificare e manutenere Difficile gestire le eccezioni con blocchi try/catch
  11. 11. Ingegneria del software mod. B FUTURES E PROMISES  Futures  Tecnica per eseguire molte operazioni in parallelo, in modo efficiente e non-blocking  Stile dichiarativo  Immutabile  Rappresenta un segnaposto per un risultato futuro  Componibili  Implementano meccanismi per la gestione delle eccezioni 11 Riccardo Cardin // With Futures (asynchronous world) val session = socialNetwork.createSessionFor("user", credentials) // Create placeholder for computation val f: Future[List[Friend]] = future { session.getFriends() } // Statements here can be executed, while waiting for results :) scala
  12. 12. Ingegneria del software mod. B FUTURES E PROMISES  Monad  Rappresenta un contesto di esecuzione (framework)  Amplificatore di tipi, computation builder  Può racchiudere un tipo  È componibile con altre monadi  Composizione (a.k.a. concatenazione) sul tipo racchiuso  Spesso permette di estrarre il valore del tipo contenuto  Caratteristica dei linguaggi funzionali 12 Riccardo Cardin public class Monad<T> { public Monad(T t) { /* ... */ } } public class Monad<T> { public abstract <V> Monad<V> bind(Function<T, Monad<V>> f); }
  13. 13. Ingegneria del software mod. B FUTURES E PROMISES  Monad  È simile ad una bolla! 13 Riccardo Cardin Può racciudere qualcosa È qualcosa di non concreto Può ricevere istruzioni su cosa fare del contenuto Può evaporare, lasciando libero il contenuto
  14. 14. Ingegneria del software mod. B FUTURES E PROMISES  Future[T]è una monad  Racchiudono l’elaborazione da eseguire in modo asincrono (callback)  Successfully completed / Failed with an exception  Eventual execution: nessun vincolo temporale 14 Riccardo Cardin import scala.util.{Success, Failure} // Asynchronous execution inside future context val f: Future[List[String]] = future { session.getRecentPosts } // Do something else... f onComplete { // onSuccess case Success(posts) => for (post <- posts) println(post) // onFailure case Failure(t) => println("An error has occured: " + t.getMessage) } posts è il risulato dell’elaborazione t è un’eccezione scala
  15. 15. Ingegneria del software mod. B FUTURES E PROMISES  Future[T]è una monad  Composizione funzionale di più elaborazioni  Non più callback hell!!!  Si riporta il modello asincrono al modello sincrono  Se un future nella catena fallisce, fallisce l’intera catena 15 Riccardo Cardin // First future execution val rateQuote = future { connection.getCurrentValue(USD) } // Bind second execution to first val purchase = rateQuote map { quote => if (isProfitable(quote)) connection.buy(amount, quote) else throw new Exception("not profitable") } // Get final result purchase onSuccess { case _ => println("Purchased " + amount + " USD") } scala
  16. 16. Ingegneria del software mod. B FUTURES E PROMISES  Promise[T]  Single-assigment container (monad) / proxy  Un Future legge il risultato di un’elaborazione asincrona  Una Promise scrive (completa) un Future 16 Riccardo Cardin val p = promise[T] // Future that is completed by the promise val f = p.future val consumer = future { startDoingSomething() f onSuccess { case r => doSomethingWithResult() } } val producer = future { val r = produceSomething() p success r // Promise completes the Future // It should be „p failure exception‟ also continueDoingSomethingUnrelated() } produceSomething startDoingSomething doSomethingWithResult r scala Valore che rappresenta l’elaborazione
  17. 17. Ingegneria del software mod. B FUTURES E PROMISES  Javascript promises (Q library)  Promise e future sono fusi nelle medesime strutture  Promise stile Scala  Q Deferreds 17 Riccardo Cardin promiseMeSomething() // value is the return value of promiseMeSomething .then(function (value) { // Do something as soon as promiseMeSomething finishes }, // Something went wrong, reason is an exception function (reason) { }); then ritona una promise, quindi è concatenabile var deferred = Q.defer(); FS.readFile("foo.txt", "utf-8", function (error, text) { if (error) { deferred.reject(new Error(error)); } else { deferred.resolve(text); } }); return deferred.promise; Deferred permette di completare una promise. concatenabile
  18. 18. Ingegneria del software mod. B FUTURES E PROMISES  Java 8 promises: CompletableFuture<T>  Creazione (usando le lambda extension)  Composizione (future stile Scala) 18 Riccardo Cardin A Future that may be explicitly completed (setting its value and status), and may include dependent functions and actions that trigger upon its completion. Javadoc final CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { //...long running... return "42"; }, executor); Effettua l’override del metodo CompletableFuture.get() // f1 is a promise that will completed with an Integer value CompletableFuture<Double> f3 = f1.thenApply(Integer::parseInt).thenApply(r -> r * r * Math.PI). exceptionally(ex -> "We have a problem: " + ex.getMessage()); thenApply è simile a map di Scala
  19. 19. Ingegneria del software mod. B REACTIVE EXTENSIONS (RX)  Gestione sequenze di valori in modo asincrono  Observable sequences  Estensione del design pattern Observer  Utilizzo di operatori di composizione (monads!) 19 Riccardo Cardin Single items Multiple items Synchronous T getData() Iterable<T> getData() Asynchronous Future<T> getData() Observable<T> getData public static void hello(String... names) { Observable.from(names).subscribe(new Action1<String>() { @Override public void call(String s) { System.out.println("Hello " + s + "!"); } }); } // hello("Ben", "George");  Hello Ben! Hello George!
  20. 20. Ingegneria del software mod. B REACTIVE EXTENSIONS (RX)  Observables (RxJava) 20 Riccardo Cardin Event Iterable (pull) Observable (push) Retrieve data T next() onNext(T) Discover error throws Exception onError(Exception) Complete returns onCompleted() Aggiunta al pattern GoF getVideos().subscribe(new Observer<Video>() { def void onNext(Video video) { // Invoked on next element println(“Video: ” + video.videoId) } def void onError(Exception e) { // Invoked on error e.printStackTrace() } def void onCompleted() { // Invoked when stream finishes to emit println(“Completed”) } }
  21. 21. Ingegneria del software mod. B REACTIVE EXTENSIONS (RX)  Observables (RxJava)  Monads  Componibili  Mantengono la proprietà di asincronia originaria 21 Riccardo Cardin
  22. 22. Ingegneria del software mod. B REACTIVE EXTENSIONS (RX)  Composizione Observables 22 Riccardo Cardin
  23. 23. Ingegneria del software mod. B ACTOR MODEL  Reactive  Elaborazioni solo in risposta a stimoli esterni  Dormiente / attivo  Non c’è un concetto esplicito di thread  Tre azioni fondamentali  Invio di un messaggio async a se stesso o altro attore  Creazione nuovi attori  Modifica del proprio comportamento  Nessuno stato interno (...in teoria...)  Immutabili 23 Riccardo Cardin Each actor is a form of reactive object, executing some computation in response to a message and sending out a reply when the computation is done John C. Mitchell
  24. 24. Ingegneria del software mod. B ACTOR MODEL  Messaggi (task)  Interfaccia di comunicazione dell’attore  Variare nel tempo (comportamento)  Elaborazione dei messaggi uno per volta  Coda di messaggi (mail box)  Nessuna garanzia sull’ordine di arrivo  Mail system  Ogni attore ha associato un mail address  Composti di tre parti 24 Riccardo Cardin tag target data email address del receiver operazione
  25. 25. Ingegneria del software mod. B ACTOR MODEL  Esempio  Ad ogni cambio di stato viene creato un nuovo attore  State change: no race conditions  Behavioural change 25 Riccardo Cardin A1:[1, 4, 7] A1:[1, 2, 4, 7] A1:[2, 4, 7] Insert|2 Get_min Min|1
  26. 26. Ingegneria del software mod. B ACTOR MODEL  Akka  Toolkit e runtime che implementano attori su JVM 26 Riccardo Cardin (c) http://akka.io
  27. 27. Ingegneria del software mod. B AKKA 27 Riccardo Cardin type Receive = PartialFunction[Any, Unit] trait Actor { def receive: Receive // Actor actual behaviour implicit val self: ActorRef // Reference to itself def sender: ActorRef // Reference to the sender of last message implicit val context: ActorContext // Execution context } abstract class ActorRef { // Send primitives def !(msg: Any)(implicit sender: ActorRef = Actor.noSender): Unit def tell(msg: Any, sender: ActorRef) = this.!(msg)(sender) // ... } trait ActorContext { // Change behaviour of an Actor def become(behavior: Receive, discardOld: Boolean = true): Unit def unbecome(): Unit // Create a new Actor def actorOf(p: Props, name: String): ActorRef def stop(a: ActorRef): Unit // Stop an Actor // ... } scala
  28. 28. Ingegneria del software mod. B AKKA  Esempio  Implementazione di un contatore con gli attori 28 Riccardo Cardin class Counter extends Actor { // State == explicit behaviour def counter(n: Int): Receive = { // Receive two types of messages: „incr‟ and „get‟ // „incr‟ change actor‟s behaviour case ”incr” => context.become(counter(n + 1)) // „get‟ returns current counter value to sender case ”get” => sender ! n } def receive = counter(0) // Default behaviour } scala a:[0] a!incr a:[1] a!incr a:[2] a!get sender!2 È possibile modellare anche stati interni
  29. 29. Ingegneria del software mod. B AKKA  Resilienza  Contenimento e riposte automatiche agli errori  Gli attori in errore vengono terminati o riavviati  La decisione è presa da un attore supervisore  Gli attori con supervisione formano una struttura ad albero  Il supervisore crea i suoi subordinati 29 Riccardo Cardin class Manager extends Actor { // OneForOneStrategy restarts only actor which died override val supervisorStrategy = OneForOneStrategy() { case _: DBException => Restart // reconnect to DB case _: ActorKilledException => Stop case _: ServiceDownException => Escalate } // ... context.actorOf(Props[DBActor], ”db”) // ... } sup sub1 sub2 sub1.1 Errorflow
  30. 30. Ingegneria del software mod. B AKKA  Actor lifecycle 30 Riccardo Cardin Start Restart Stop new Actor preStart fail preStart new Actor stop postStop Supervisor An actor ActorRef rimane valido tra un riavvio e l’altro Le fasi di riavvio possono essere molteplici
  31. 31. Ingegneria del software mod. B BIBLIOGRAFIA  The Reactive Manifesto http://www.reactivemanifesto.org/  Promises in Node.js with Q – An Alternative to Callbacks http://strongloop.com/strongblog/promises-in-node-js-with-q- an-alternative-to-callbacks/  The Reactive Extensions (Rx) http://msdn.microsoft.com/en- us/data/gg577609.aspx  Futures and Promises http://docs.scala- lang.org/overviews/core/futures.html  Java concurrency (multi-threading) http://www.vogella.com/tutorials/JavaConcurrency/article.html #futures  Java 8: Definitive guide to CompletableFuture http://nurkiewicz.blogspot.it/2013/05/java-8-definitive-guide- to.html  Taming asynchronous programming http://eamodeorubio.github.io/tamingasync/#/ 31 Riccardo Cardin
  32. 32. Ingegneria del software mod. B BIBLIOGRAFIA  Monadic futures in Java 8 http://zeroturnaround.com/rebellabs/monadic-futures-in-java8/  Monads http://ericlippert.com/category/monads/  Callback Hell http://callbackhell.com/  CompletableFuture http://www.slideshare.net/kojilin/completable-future  RxJava Wiki https://github.com/Netflix/RxJava/wiki  Functional Reactive Programming with RxJava https://speakerdeck.com/benjchristensen/functional-reactive- programming-with-rxjava-javaone-2013  Principle of Reactive Programming https://class.coursera.org/reactive-001  Actors http://doc.akka.io/docs/akka/snapshot/scala/actors.html 32 Riccardo Cardin

×