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 PRINCIPI DI  Accedute da dispositivi desktop  Applicazione moderne (≥ 2010) REACTIVE PROGRAMMING  Cluster di migliaia di processi multicore INGEGNERIA DEL SOFTWARE  Tempi di risposta nell’ordine dei millisec Università degli Studi di Padova Dipartimento di Matematica  100% uptime Corso di Laurea in Informatica, A.A. 2013 – 2014  Dati nell’ordine dei Petabyte 2  Accedute da qualsiasi tipo di dispositivo

[email protected] Ingegneria del software mod. B Riccardo Cardin

GO REACTIVE! REACTIVE MANIFESTO • Real-time, engaging, reach, • Nessun redesing per  Nuovi requisiti richiedono nuove tecnologie collaborative ottenere la scalabilità • Nessuna latenza nelle  Reactive Application • Scalabilità on-demand risposte  Orientate agli eventi • Risk-management

 Scalabili "Readily responsive to a stimulus" responsive  Resilienti Merriam-Webster  Responsive

react to events react to load scalable resilient La natura event-driven abilita La scalabilità non deve dipendere alle altre qualità da risorse condivise event-driven • Downtime è perdita di denaro react to failure react to users • Parte del design Sistemi resilienti permettono I tempi di risposta non devono • Loosely coupled design di recuperare errori a tutti dipendere dal carico di lavoro • Communication orientation i livelli 3 4 • Uso efficiente delle risorse

Ingegneria del software mod. B Riccardo Cardin Ingegneria del software mod. B Riccardo Cardin MODELLO SINCRONO MODELLO SINCRONO

 Il mondo sincrono è senza futuro...  Il mondo sincrono è senza futuro... // Synchronous world (w/o Future)  Esempio: recuperare il nome del file più pesante val session = socialNetwork.createSessionFor("user", credentials) // blocked on method, waiting for results (latency)... public String getBiggestFile(final File folder) { session.getFriends() long maxLength = 0L; // There are a lot of operation to do!!! :( String fileName = null; for (final File fileEntry : folder.listFiles()) {  Frequenti operazioni di I/O if (maxLength < fileEntry.length()) { // Not so efficient fileName = fileEntry.getName();  Scarso utilizzo delle feature offerte dai processori moderni maxLength = fileEntry.length(); }  Larga diffusione delle architetture multiprocessore }  Cicli non ottimizzati return fileName ; }  Scarso parallelismo o gestione difficoltosa Java fileEntry.length() // I/O if (maxLength… // computation  Tipico dei linguaggi imperativi ad oggetti  C, C++, Java, ...... 5 6 Tempo totale di attesa CPU poco utilizzata, I/O sovrabbondante Ingegneria del software mod. B Riccardo Cardin Ingegneria del software mod. B Riccardo Cardin

MODELLO ASINCRONO MODELLO ASINCRONO

 Callbacks  Callbacks  Funzioni da invocare al termine di una elaborazione CPU1  Gestione migliore della CPU CPU2  Ridotti tempi di attesa I/O è ancora presente, ma viene distribuito  Più processi gestiscono più richieste CPU3 sull’elaborazione di più CPU  Asynchronous JavaScript and XML (AJAX) CPU4 var callback = function(){ alert('I was called back asynchronously'); Tempo totale di attesa }; In attesa della risposta, è $.ajax({  Linguaggi o framework che gestiscano l’elaborazione type: 'GET', possibile continuare asincrona e concorrente url: 'http://example.com', l’elaborazione (rendering UI) done: callback, // positive case  Node.js, jQuery, ... fail: anotherCallback // negative case 7  Ma...c’è sempre un ma... 8 }); jQuery

Ingegneria del software mod. B Riccardo Cardin Ingegneria del software mod. B Riccardo Cardin module.exports = function (dir, cb) { fs.readdir(dir, function (er, files) { if (er) return cb(er) Difficile gestire le var counter = files.length eccezioni con blocchi MODELLO ASINCRONO var errored = false try/catch var stats = []

 Callbacks...HELL!!! files.forEach(function (file, index) { fs.stat(path.join(dir,file), function (er, stat) { if (errored) return if (er) { errored = true Innesto callback per gestire return cb(er) i flussi degli eventi } 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] Difficile da verificare }) // [2] 9 e manutenere 10 }) // [3] } node.js Ingegneria del software mod. B Riccardo Cardin Ingegneria del software mod. B Riccardo Cardin

FUTURES E PROMISES FUTURES E PROMISES

 Futures  Monad  Tecnica per eseguire molte operazioni in parallelo, in  Rappresenta un contesto di esecuzione (framework)

modo efficiente e non-blocking  Amplificatore di tipi, computation builder

 Stile dichiarativo  Può racchiudere un tipo

 Immutabile public class Monad {  Rappresenta un segnaposto per un risultato futuro public Monad(T t) { /* ... */ } }

 Componibili  È componibile con altre monadi  Implementano meccanismi per la gestione delle eccezioni  Composizione (a.k.a. concatenazione) sul tipo racchiuso // With Futures (asynchronous world) val session = socialNetwork.createSessionFor("user", credentials) public class Monad { // Create placeholder for computation public abstract Monad bind(Function> f); val f: Future[List[Friend]] = future { session.getFriends() } } // Statements here can be executed, while waiting for results :)  Spesso permette di estrarre il valore del tipo contenuto scala 11 12  Caratteristica dei linguaggi funzionali

Ingegneria del software mod. B Riccardo Cardin Ingegneria del software mod. B Riccardo Cardin FUTURES E PROMISES FUTURES E PROMISES

 Monad  Future[T] è una monad  È simile ad una bolla! Può racciudere  Racchiudono l’elaborazione da eseguire in modo qualcosa asincrono (callback)

È qualcosa di  Successfully completed / Failed with an exception non concreto  Eventual execution: nessun vincolo temporale

import scala.util.{Success, Failure} // Asynchronous execution inside future context val f: Future[List[String]] = future { Può session.getRecentPosts evaporare, } è il risulato lasciando // Do something else... posts libero il f onComplete { dell’elaborazione // onSuccess contenuto case Success(posts) => for (post <- posts) println(post) // onFailure case Failure(t) => println("An error has occured: " + Può ricevere istruzioni su 13 t.getMessage) 14 } cosa fare del contenuto t è un’eccezione scala Ingegneria del software mod. B Riccardo Cardin Ingegneria del software mod. B Riccardo Cardin

FUTURES E PROMISES FUTURES E PROMISES Valore che rappresenta l’elaborazione  Future[T] è una monad  Promise[T]  Composizione funzionale di più elaborazioni  Single-assigment container (monad) / proxy

 Non più callback hell!!!  Un Future legge il risultato di un’elaborazione asincrona

 Si riporta il modello asincrono al modello sincrono  Una Promise scrive (completa) un Future

 Se un future nella catena fallisce, fallisce l’intera catena val p = promise[T] scala // Future that is completed by the promise // First future execution val f = p.future val rateQuote = future { val consumer = future { connection.getCurrentValue(USD) startDoingSomething() } f onSuccess { // Bind second execution to first case => doSomethingWithResult() r val purchase = rateQuote map { quote => } if (isProfitable(quote)) connection.buy(amount, quote) } produceSomething else throw new Exception("not profitable") val producer = future { } val r = produceSomething() startDoingSomething // Get final result p success r // Promise completes the Future purchase onSuccess { // It should be ‘p failure exception’ also 15 doSomethingWithResult 16 case _ => println("Purchased " + amount + " USD") continueDoingSomethingUnrelated() } scala } Ingegneria del software mod. B Riccardo Cardin Ingegneria del software mod. B Riccardo Cardin FUTURES E PROMISES FUTURES E PROMISES

 Javascript promises (Q library)  Java 8 promises: CompletableFuture  Promise e future sono fusi nelle medesime strutture A Future that may be explicitly completed (setting its value promiseMeSomething() and status), and may include dependent functions and actions // value is the return value of promiseMeSomething .then(function (value) { that trigger upon its completion. // Do something as soon as promiseMeSomething finishes Javadoc }, // Something went wrong, reason is an exception then ritona una  Creazione (usando le lambda extension) function (reason) { }); promise, quindi è final CompletableFuture future = Effettua l’override del concatenabile CompletableFuture .supplyAsync(() -> { metodo  Promise stile Scala  Q Deferreds //...long running... CompletableFuture.get() return "42" ; var deferred = Q.defer(); }, executor); FS.readFile("foo.txt", "utf-8", function (error, text) { è simile a thenApply map if (error) { deferred.reject(new Error(error)); }  Composizione (future stile Scala) di Scala else { deferred.resolve(text); } // f1 is a promise that will completed with an Integer value }); permette di CompletableFuture f3 = return deferred.promise; Deferred 17 18 completare una promise. f1.thenApply(Integer::parseInt).thenApply(r -> r * r * Math.PI). exceptionally(ex -> "We have a problem: " + ex.getMessage()); concatenabile Ingegneria del software mod. B Riccardo Cardin Ingegneria del software mod. B Riccardo Cardin

REACTIVE EXTENSIONS (RX) REACTIVE EXTENSIONS (RX)

 Gestione sequenze di valori in modo asincrono  Observables (RxJava)  Observable sequences Event Iterable (pull) Observable (push) Single items Multiple items Retrieve data T next() onNext(T) T getData() Iterable getData() throws Synchronous Discover error Exception onError(Exception) Aggiunta al Asynchronous Future getData() Observable getData Complete returns onCompleted() pattern GoF  Estensione del design pattern Observer getVideos().subscribe(new Observer

 Observables (RxJava)  Composizione Observables  Monads  Componibili

 Mantengono la proprietà di asincronia originaria

21 22

Ingegneria del software mod. B Riccardo Cardin Ingegneria del software mod. B Riccardo Cardin

ACTOR MODEL

Each actor is a form of reactive object, executing some  Messaggi (task) computation in response to a message and sending out a  Interfaccia di comunicazione dell’attore reply when the computation is done John C. Mitchell  Variare nel tempo (comportamento)  Elaborazione dei messaggi uno per volta  Reactive  Coda di messaggi (mail box)

 Elaborazioni solo in risposta a stimoli esterni  Nessuna garanzia sull’ordine di arrivo  Dormiente / attivo  Mail system

 Non c’è un concetto esplicito di thread  Ogni attore ha associato un mail address  Tre azioni fondamentali  Composti di tre parti  Invio di un messaggio async a se stesso o altro attore tag target data  Creazione nuovi attori  Modifica del proprio comportamento 23 operazione email address del 24  Nessuno stato interno (...in teoria...)  Immutabili receiver

Ingegneria del software mod. B Riccardo Cardin Ingegneria del software mod. B Riccardo Cardin ACTOR MODEL ACTOR MODEL

 Esempio  Akka  Ad ogni cambio di stato viene creato un nuovo attore  Toolkit e runtime che implementano attori su JVM

 State change: no race conditions

 Behavioural change Get_min

Min|1 Insert|2 A1:[1, 2, 4, 7] A1:[1, 4, 7]

A1:[2, 4, 7] 25 26 (c) http://akka.io

Ingegneria del software mod. B Riccardo Cardin Ingegneria del software mod. B Riccardo Cardin

AKKA AKKA scala type Receive = PartialFunction[Any, Unit]  trait Actor { Esempio def receive: Receive // Actor actual behaviour  Implementazione di un contatore con gli attori implicit val self: ActorRef // Reference to itself def sender: ActorRef // Reference to the sender of last message class Counter extends Actor { implicit val context: ActorContext // Execution context // State == explicit behaviour È possibile } def counter(n: Int): Receive = { abstract class ActorRef { modellare // Receive two types of messages: ‘incr’ and ‘get’ anche // Send primitives // ‘incr’ change actor’s behaviour def !(msg: Any)(implicit sender: ActorRef = Actor.noSender): Unit case ”incr” => context.become(counter(n + 1)) stati def tell(msg: Any, sender: ActorRef) = this.!(msg)(sender) // ‘get’ returns current counter value to sender interni // ... case ”get” => sender ! n } } trait ActorContext { def receive = counter(0) // Default behaviour // Change behaviour of an Actor } def become(behavior: Receive, discardOld: Boolean = true): Unit scala def unbecome(): Unit // Create a new Actor a!incr a!incr a!get sender!2 def actorOf(p: Props, name: String): ActorRef def stop(a: ActorRef): Unit // Stop an Actor // ... 27 a:[0] a:[1] a:[2] 28 }

Ingegneria del software mod. B Riccardo Cardin Ingegneria del software mod. B Riccardo Cardin sup sub1 AKKA sub2 AKKA

Error flow sub1.1 Supervisor  Resilienza  Actor lifecycle  Contenimento e riposte automatiche agli errori An actor Start  Gli attori in errore vengono terminati o riavviati new Actor  La decisione è presa da un attore supervisore preStart

 Gli attori con supervisione formano una struttura ad albero Le fasi di riavvio fail  Il supervisore crea i suoi subordinati possono essere molteplici class Manager extends Actor { Restart // OneForOneStrategy restarts only actor which died override val supervisorStrategy = OneForOneStrategy() { preStart case _: DBException => Restart // reconnect to DB new Actor case _: ActorKilledException => Stop case _: ServiceDownException => Escalate ActorRef rimane } valido tra un // ... riavvio e l’altro stop context.actorOf(Props[DBActor], ”db”) Stop // ... 29 30 } postStop Ingegneria del software mod. B Riccardo Cardin Ingegneria del software mod. B Riccardo Cardin

BIBLIOGRAFIA BIBLIOGRAFIA

 The Reactive Manifesto http://www.reactivemanifesto.org/  Monadic futures in Java 8  Promises in Node.js with Q – An Alternative to Callbacks http://zeroturnaround.com/rebellabs/monadic-futures-in- http://strongloop.com/strongblog/promises-in-node-js-with- java8/ q-an-alternative-to-callbacks/  Monads http://ericlippert.com/category/monads/  The Reactive Extensions (Rx) http://msdn.microsoft.com/en- us/data/gg577609.aspx  Callback Hell http://callbackhell.com/  Futures and Promises http://docs.scala-  CompletableFuture lang.org/overviews/core/futures.html http://www.slideshare.net/kojilin/completable-future  Java concurrency (multi-threading)  RxJava Wiki https://github.com/Netflix/RxJava/wiki http://www.vogella.com/tutorials/JavaConcurrency/article.h  Functional Reactive Programming with RxJava tml#futures https://speakerdeck.com/benjchristensen/functional-  Java 8: Definitive guide to CompletableFuture reactive-programming-with-rxjava-javaone-2013 http://nurkiewicz.blogspot.it/2013/05/java-8-definitive- guide-to.html  Principle of Reactive Programming  Taming asynchronous programming https://class.coursera.org/reactive-001 http://eamodeorubio.github.io/tamingasync/#/  31 Actors 32 http://doc.akka.io/docs/akka/snapshot/scala/actors.html

Ingegneria del software mod. B Riccardo Cardin Ingegneria del software mod. B Riccardo Cardin