concepts and technologies for distributed systems and big ... · philipp haller flatmap combinator...
TRANSCRIPT
![Page 1: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/1.jpg)
Concepts and Technologiesfor
Distributed Systems and Big Data Processing
Philipp HallerKTH Royal Institute of Technology
Stockholm, Sweden
TU Darmstadt, Germany, 19 May and 26 May 2017
Futures, Async, and Actors
![Page 2: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/2.jpg)
Philipp Haller
About Myself• 2006 Dipl.-Inform.
Karlsruhe Institute of Technology (KIT), Germany
• 2010 Ph.D. in Computer ScienceSwiss Federal Institute of Technology Lausanne (EPFL), Switzerland
• 2011–2012 Postdoctoral FellowStanford University, USA, and EPFL, Switzerland
• 2012–2014 Consultant and software engineerTypesafe, Inc.
• 2014—present Assistant Professor of Computer ScienceKTH Royal Institute of Technology, Sweden
2
![Page 3: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/3.jpg)
Philipp Haller
Programming a Concurrent World
• How to compose programs handling
• asynchronous events?
• streams of asynchronous events?
• distributed events?
➟ Programming abstractions for concurrency!
3
![Page 4: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/4.jpg)
Philipp Haller
Overview
• Futures and promises
• Async/await
• Actors
4
![Page 5: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/5.jpg)
Philipp Haller
Why a Growable Language for Concurrency?
• Concurrency not a solved problem ➟ development of new programming models
5
• Futures, promises
• Async/await
• STM
• Agents
• Actors
• Join-calculus
• Reactive streams
• CSP
• CML
• …Which one is going to “win”?
![Page 6: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/6.jpg)
Philipp Haller
Background
• Authored or co-authored:
• Scala Actors (2006)
• Scala futures and promises (2011/2012)
• Scala Async (2013)
• Contributed to Akka (Typesafe/Lightbend)
• Akka.js project (2014)
6
Other proposals and research projects:
• Scala Joins (2008)
• FlowPools (2012)
• Spores (safer closures)
• Capabilities and uniqueness
• …
![Page 7: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/7.jpg)
Philipp Haller
Scala Primer
• Local variables: val x = fun(arg) // type inference
• Collections: val list = List(1, 2, 3) // list: List[Int]
• Functions:
• { param => fun(param) }
• (param: T) => fun(param)
• Function type: T => S or (T, S) => U
7
![Page 8: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/8.jpg)
Philipp Haller
Scala Primer (2)
8
• Methods: def meth(x: T, y: S): R = { .. }
• Classes: class C extends D { .. }
• Generics:
• class C[T] { var fld: T = _ ; .. }
• def convert[T](obj: T): Result = ..
![Page 9: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/9.jpg)
Philipp Haller
Scala Primer (3)
9
• Case classes and pattern matching:
• case class Person(name: String, age: Int)
• val isAdult = p match { case Person(_, a) => a >= 18 case Alien(_, _) => false }
![Page 10: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/10.jpg)
Philipp Haller
Example
• Common task:
• Convert object to JSON
• Send HTTP request containing JSON
10
import scala.util.parsing.json._
def convert[T](obj: T): Future[JSONType] def sendReq(json: JSONType): Future[JSONType]
![Page 11: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/11.jpg)
Latency numbers every programmer should know
L1 cache reference 0.5nsBranch mispredict 5nsL2 cache reference 7nsMutex lock/unlock 25nsMain memory reference 100nsCompress 1K bytes with Zippy 3,000nsSend 2K bytes over 1Gbps network 20,000nsSSD random read 150,000nsRead 1 MB sequentially from memory 250,000nsRoundtrip within same datacenter 500,000nsRead 1MB sequentially from SSD 1,000,000nsDisk seek 10,000,000nsRead 1MB sequentially from disk 20,000,000nsSend packet US → Europe → US 150,000,000ns
= 3μs= 20μs= 150μs= 250μs= 0.5ms= 1ms= 10ms= 20ms= 150ms
Original compilation by Peter Norvig, w/ contributions by Joe Hellerstein & Erik Meijer
![Page 12: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/12.jpg)
Latency numbers: humanized!
L1 cache reference 0.5 s One heart beatBranch mispredict 5 s YawnL2 cache reference 7 s Long yawnMutex lock/unlock 25 s Making a coffee
Main memory reference 100 s Brushing your teeth
Compress 1KB with Zippy 50 min One episode of a TV show
Seconds:
Minutes:
![Page 13: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/13.jpg)
Latency numbers: humanized!
Send 2KB over 1 Gbps network 5.5 hr From lunch to end
of work day
Hours:
Days:SSD random read 1.7 days A normal weekendRead 1MB sequentially from memory 2.9 days A long weekend
Round trip within same datacenter 5.8 days A medium vacation
Read 1MB sequentially from SSD
11.6 days Waiting almost 2 weeks for a delivery
![Page 14: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/14.jpg)
Latency numbers: humanized!
Months:
Years:
Disk seek 16.5 weeks A semester at university
Read 1MB sequentially from disk
7.8 months Almost producing a new human being
The above 2 together 1 year
Send packet US → Europe → US
4.8 years Average time it takes to complete a bachelor’s degree
![Page 15: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/15.jpg)
Philipp Haller
Callbacks
• How to respond to asynchronous completion event?
➟ Register callback
15
val person = Person(“Tim”, 25)
val fut: Future[JSONType] = convert(person)
fut.foreach { json => val resp: Future[JSONType] = sendReq(json) .. }
![Page 16: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/16.jpg)
Philipp Haller
Exceptions
• Serialization to JSON may fail at runtime
• Closure passed to foreach not executed in this case
• How to handle asynchronous exceptions?
16
val fut: Future[JSONType] = convert(person)
fut.onComplete { case Success(json) => val resp: Future[JSONType] = sendReq(json) case Failure(e) => e.printStackTrace() }
![Page 17: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/17.jpg)
Philipp Haller
Partial Functions
17
{ case Success(json) => .. case Failure(e) => .. }
… creates an instance of PartialFunction[T, R]:
val pf: PartialFunction[Try[JSONType], Any] = { case Success(json) => .. case Failure(e) => .. }
![Page 18: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/18.jpg)
Philipp Haller
Type of Partial Functions
• Partial functions have a type PartialFunction[A, B]
• PartialFunction[A, B] is a subtype of Function1[A, B]
18
abstract class Function1[A, B] { def apply(x: A): B .. }
abstract class PartialFunction[A, B] extends Function1[A, B] { def isDefinedAt(x: A): Boolean def orElse[A1 <: A, B1 >: B] (that: PartialFunction[A1, B1]): PartialFunction[A1, B1] .. }
Simplified!
Actually: trait rather than abstract class
![Page 19: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/19.jpg)
Philipp Haller
Success and Failure
19
package scala.util
sealed abstract class Try[+T]
final case class Success[+T](v: T) extends Try[T]
final case class Failure[+T](e: Throwable) extends Try[T]
![Page 20: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/20.jpg)
Philipp Haller
Nested Exceptions
➟ Exception handling tedious and not compositional:
20
val fut: Future[JSONType] = convert(person)
fut.onComplete { case Success(json) => val resp: Future[JSONType] = sendReq(json) resp.onComplete { case Success(jsonResp) => .. // happy path case Failure(e1) => e1.printStackTrace(); ??? } case Failure(e2) => e2.printStackTrace(); ??? }
![Page 21: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/21.jpg)
Philipp Haller
Failed Futures
• Future[T] is completed with Try[T], i.e., with success or failure
• Combinators enable compositional failure handling
• Example:
21
val resp: Future[JSONType] = sendReq(json) val processed = resp.map { jsonResp => .. // happy path }
Encapsulates failure
![Page 22: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/22.jpg)
Philipp Haller
Map Combinator• Creates a new future by applying a function to the
successful result of the receiver future
• If the function application results in an uncaught exception e then the new future is completed with e
• If the receiver future is completed with an exception e then the new future is also completed with e
22
abstract class Future[+T] extends Awaitable[T] {
def map[S](f: T => S)(implicit ..): Future[S]
// .. }
![Page 23: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/23.jpg)
Philipp Haller
Future Composition
23
val fut: Future[JSONType] = convert(person)
val processed = fut.map { json => val resp: Future[JSONType] = sendReq(json) resp.map { jsonResp => .. // happy path } }
Encapsulates all failures
Problem: processed has type
Future[Future[T]]
![Page 24: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/24.jpg)
Philipp Haller
Future Pipelining
Future pipelining: the result of the inner future (result of
map) determines the result of the outer future (processed)
24
val fut: Future[JSONType] = convert(person)
val processed = fut.flatMap { json => val resp: Future[JSONType] = sendReq(json) resp.map { jsonResp => .. // happy path } }
![Page 25: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/25.jpg)
Philipp Haller
FlatMap Combinator• Creates a new future by applying a function to the
successful result of the receiver future
• The future result of the function application determines the result of the new future
• If the function application results in an uncaught exception e then the new future is completed with e
• If the receiver future is completed with an exception e then the new future is also completed with e
25
def flatMap[S](f: T => Future[S])(implicit ..): Future[S]
![Page 26: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/26.jpg)
Philipp Haller
Creating Futures• Futures are created based on (a) computations, (b) events,
or (c) combinations thereof
• Creating computation-based futures:
26
object Future {
def apply[T](body: => T)(implicit ..): Future[T]
}Singleton object
“Code block” with result type T
“Unrelated” to the singleton
object!
![Page 27: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/27.jpg)
Philipp Haller
Futures: Example
27
val firstGoodDeal = Future { usedCars.find(car => isGoodDeal(car)) }
val firstGoodDeal = Future.apply({ usedCars.find(car => isGoodDeal(car)) })
Short syntax for:
Type inference:
val firstGoodDeal = Future.apply[Option[Car]]({ usedCars.find(car => isGoodDeal(car)) })
Type Future[Option[Car]]
![Page 28: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/28.jpg)
Philipp Haller
Creating Futures: Operationally• Invoking the shown factory method creates a task object
encapsulating the computation
• The task object is scheduled for execution by an execution context
• An execution context is capable of executing tasks, typically using a thread pool
• Future tasks are submitted to the current implicit execution context
28
def apply[T](body: => T)(implicit executor: ExecutionContext): Future[T]
![Page 29: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/29.jpg)
Philipp Haller
Implicit Execution ContextsImplicit parameter requires selecting a execution context
29
???
an (implicit ec: ExecutionContext) parameter to your method or import scala.concurrent.ExecutionContext.Implicits.global. val fut = Future { 40 + 2 } ^
<console>:10: error: Cannot find an implicit ExecutionContext. You might pass
Welcome to Scala 2.12.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_..). Type in expressions for evaluation. Or try :help.
scala> import scala.concurrent._ import scala.concurrent._
scala> val fut = Future { 40 + 2 } But…
![Page 30: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/30.jpg)
Philipp Haller
Execution Contexts
• Interface for asynchronous task executors
• May wrap a java.util.concurrent.{Executor, ExecutorService}
30
![Page 31: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/31.jpg)
Philipp Haller
Collections of Futures
31
val reqFuts: List[Future[JSONType]] = ..
val smallestRequest: Future[JSONType] = Future.sequence(reqFuts).map( reqs => selectSmallestRequest(reqs) )
![Page 32: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/32.jpg)
Philipp Haller
Promise
Main purpose: create futures for non-lexically-scoped asynchronous code
32
def after[T](delay: Long, value: T): Future[T]
Example
Function for creating a Future that is completed with value after delay milliseconds
![Page 33: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/33.jpg)
Philipp Haller
“after”, Version 1
33
def after1[T](delay: Long, value: T) = Future { Thread.sleep(delay) value }
![Page 34: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/34.jpg)
Philipp Haller
“after”, Version 1
34
assert(Runtime.getRuntime() .availableProcessors() == 8)
for (_ <- 1 to 8) yield after1(1000, true)
val later = after1(1000, true)
How does it behave?
Quiz: when is “later” completed?
Answer: after either ~1 s or ~2 s (most often)
![Page 35: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/35.jpg)
Philipp Haller
Promise
35
object Promise { def apply[T](): Promise[T] }
trait Promise[T] { def success(value: T): Promise[T] def failure(cause: Throwable): Promise[T]
def future: Future[T] }
![Page 36: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/36.jpg)
Philipp Haller
“after”, Version 2
36
def after2[T](delay: Long, value: T) = { val promise = Promise[T]() timer.schedule(new TimerTask { def run(): Unit = promise.success(value) }, delay) promise.future }
Much better behaved!
![Page 37: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/37.jpg)
Philipp Haller
Futures and Promises: Conclusion
• Scala enables flexible concurrency abstractions
• Futures: high-level abstraction for asynchronous events and computations
• Combinators instead of callbacks
• Promises enable integrating futures with any event-driven API
37
![Page 38: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/38.jpg)
Philipp Haller
Overview
• Futures, promises
• Async/await
• Actors
38
![Page 39: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/39.jpg)
Philipp Haller
What is Async?
• Scala module
• "org.scala-lang.modules" %% "scala-async"
• Purpose: simplify programming with futures
• Scala Improvement Proposal SIP-22
• Releases for Scala 2.10, 2.11, and 2.12
• See https://github.com/scala/async/
39
![Page 40: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/40.jpg)
Philipp Haller
What Async Provides
• Future and Promise provide types and operations for managing data flow
• Very little support for control flow
• Async complements Future and Promise with constructs to manage control flow
40
![Page 41: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/41.jpg)
Philipp Haller
Programming Model
Basis: suspendible computations
• async { .. } — delimit suspendible computation
• await(future) — suspend computation until
future is completed
41
![Page 42: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/42.jpg)
Philipp Haller
Async
42
object Async {
def async[T](body: => T): Future[T]
def await[T](future: Future[T]): T
}
![Page 43: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/43.jpg)
Philipp Haller
Example
43
val fstGoodDeal: Future[Option[Car]] = .. val sndGoodDeal: Future[Option[Car]] = ..
val goodCar = async { val car1 = await(fstGoodDeal).get val car2 = await(sndGoodDeal).get if (car1.price < car2.price) car1 else car2 }
![Page 44: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/44.jpg)
Philipp Haller
Futures vs. Async
• “Futures and Async: When to Use Which?”, Scala Days 2014, Berlin
• Video:
• Slides:
44
https://www.youtube.com/watch?v=TyuPdFDxkro
https://speakerdeck.com/phaller/futures-and-async-when-to-use-which
![Page 45: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/45.jpg)
Philipp Haller
Async in Other Languages
Constructs similar to async/await are found in a number of widely-used languages:
• C#
• Dart (Google)
• Hack (Facebook)
• ECMAScript 7 1
45
1 http://tc39.github.io/ecmascript-asyncawait/
![Page 46: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/46.jpg)
Philipp Haller
From Futures to Actors
• Limitations of futures:
• At most one completion event per future
• Overhead when creating many futures
• How to model distributed systems?
46
![Page 47: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/47.jpg)
Philipp Haller
The Actor Model• Model of concurrent computation whose universal primitive is
the “actor” [Hewitt et al. ’73]
• Actors = concurrent “processes” communicating via asynchronous messages
• Upon reception of a message, an actor may
• change its behavior/state
• send messages to actors (including itself)
• create new actors
• Fair scheduling
• Decoupling: message sender cannot fail due to receiver
47
Related to active objects
![Page 48: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/48.jpg)
Philipp Haller
Example
48
class ActorWithTasks(tasks: ...) extends Actor { ...
def receive = { case TaskFor(workers) => val from = sender
val requests = (tasks zip workers).map { case (task, worker) => worker ? task } val allDone = Future.sequence(requests) allDone andThen { seq => from ! seq.mkString(",") } } } Using Akka (http://akka.io/)
![Page 49: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/49.jpg)
Philipp Haller
Anatomy of an Actor (1)• An actor is an active object with its own behavior
• Actor behavior defined by:
• subclassing Actor
• implementing def receive
49
class ActorWithTasks(tasks: List[Task]) extends Actor { def receive = { case TaskFor(workers) => // send `tasks` to `workers` case Stop => // stop `self` } }
![Page 50: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/50.jpg)
Philipp Haller
Anatomy of an Actor (2)• Exchanged messages should be immutable
• And serializable, to enable remote messaging
• Message types should implement structural equality
• In Scala: case classes and case objects
• Enables pattern matching on the receiver side
50
case class TaskFor(workers: List[ActorRef]) case object Stop
![Page 51: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/51.jpg)
Philipp Haller
Anatomy of an Actor (3)• Actors are isolated
• Strong encapsulation of state
• Requires restricting access and creation
• Separate Actor instance and ActorRef
• ActorRef public, safe interface to actor
51
val system = ActorSystem(“test-system”) val actor1: ActorRef = system.actorOf[ActorWithTasks]
actor1 ! TaskFor(List()) // async message send
![Page 52: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/52.jpg)
Philipp Haller
Why Actors?Reason 1: simplified concurrency
• “Share nothing”: strong isolation of actors ➟ no race conditions
• Actors handle at most one message at a time➟ sequential reasoning
• Asynchronous message handling➟ less risk of deadlocks
• No “inversion of control”: access to own state and messages in safe, direct way
52
“Macro-step semantics”
![Page 53: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/53.jpg)
Philipp Haller
Why Actors? (cont’d)Reason 2: actors model reality of distributed systems
• Message sends truly asynchronous
• Message reception not guaranteed
• Non-deterministic message ordering
• Some implementations preserve message ordering between pairs of actors
Therefore, actors well-suited as a foundation for distributed systems
53
![Page 54: Concepts and Technologies for Distributed Systems and Big ... · Philipp Haller FlatMap Combinator • Creates a new future by applying a function to the successful result of the](https://reader034.vdocuments.us/reader034/viewer/2022042311/5ed914cc6714ca7f47691d3c/html5/thumbnails/54.jpg)
Philipp Haller
Summary
• Concurrency benefits from growable languages
• Futures and promises a versatile abstraction for single, asynchronous events
• Supported by async/await
• The actor model faithfully models distributed systems
54