153
Concepts and Technologies for Distributed Systems and Big Data Processing Philipp Haller KTH Royal Institute of Technology Sweden TU Darmstadt, Germany, 24 May 2016 Futures, Actors, and Streams

Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

  • Upload
    others

  • View
    7

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Concepts and Technologiesfor

Distributed Systems and Big Data Processing

Philipp HallerKTH Royal Institute of Technology

Sweden

TU Darmstadt, Germany, 24 May 2016

Futures, Actors, and Streams

Page 2: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Programming a Concurrent World

• How to compose programs handling

• asynchronous events?

• streams of asynchronous events?

• distributed events?

➟ Programming abstractions for concurrency!

2

Page 3: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Overview

• Futures, promises

• Async/await

• Actors

3

Page 4: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Why a Growable Language for Concurrency?

4

Page 5: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Why a Growable Language for Concurrency?

• Concurrency not a solved problem ➟ development of new programming models

4

Page 6: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Why a Growable Language for Concurrency?

• Concurrency not a solved problem ➟ development of new programming models

4

• Futures, promises

Page 7: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Why a Growable Language for Concurrency?

• Concurrency not a solved problem ➟ development of new programming models

4

• Futures, promises

• async/await

Page 8: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Why a Growable Language for Concurrency?

• Concurrency not a solved problem ➟ development of new programming models

4

• Futures, promises

• async/await

• STM

Page 9: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Why a Growable Language for Concurrency?

• Concurrency not a solved problem ➟ development of new programming models

4

• Futures, promises

• async/await

• STM

• Agents

Page 10: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Why a Growable Language for Concurrency?

• Concurrency not a solved problem ➟ development of new programming models

4

• Futures, promises

• async/await

• STM

• Agents

• Actors

Page 11: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Why a Growable Language for Concurrency?

• Concurrency not a solved problem ➟ development of new programming models

4

• Futures, promises

• async/await

• STM

• Agents

• Actors

• Join-calculus

Page 12: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Why a Growable Language for Concurrency?

• Concurrency not a solved problem ➟ development of new programming models

4

• Futures, promises

• async/await

• STM

• Agents

• Actors

• Join-calculus

• Reactive streams

Page 13: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Why a Growable Language for Concurrency?

• Concurrency not a solved problem ➟ development of new programming models

4

• Futures, promises

• async/await

• STM

• Agents

• Actors

• Join-calculus

• Reactive streams

• CSP

Page 14: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Why a Growable Language for Concurrency?

• Concurrency not a solved problem ➟ development of new programming models

4

• Futures, promises

• async/await

• STM

• Agents

• Actors

• Join-calculus

• Reactive streams

• CSP

• Async CML

Page 15: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Why a Growable Language for Concurrency?

• Concurrency not a solved problem ➟ development of new programming models

4

• Futures, promises

• async/await

• STM

• Agents

• Actors

• Join-calculus

• Reactive streams

• CSP

• Async CML

• …

Page 16: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Why a Growable Language for Concurrency?

• Concurrency not a solved problem ➟ development of new programming models

4

• Futures, promises

• async/await

• STM

• Agents

• Actors

• Join-calculus

• Reactive streams

• CSP

• Async CML

• …Which one is going to “win”?

Page 17: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Background

5

Page 18: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Background

• Authored or co-authored:

• Scala Actors (2006)

• Scala futures and promises (2011/2012)

• Scala Async (2013)

5

Page 19: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Background

• Authored or co-authored:

• Scala Actors (2006)

• Scala futures and promises (2011/2012)

• Scala Async (2013)

• Contributed to Akka (Typesafe/Lightbend)

5

Page 20: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

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)

5

Page 21: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

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)

5

Other proposals and research projects:

• Scala Joins (2008)

• FlowPools (2012)

• Spores (safer closures)

• Capabilities and uniqueness

• …

Page 22: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Scala Primer

6

Page 23: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Scala Primer

• Local variables: val x = fun(arg) // type inference

6

Page 24: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Scala Primer

• Local variables: val x = fun(arg) // type inference

• Functions:

6

Page 25: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Scala Primer

• Local variables: val x = fun(arg) // type inference

• Functions:

• { param => fun(param) }

6

Page 26: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Scala Primer

• Local variables: val x = fun(arg) // type inference

• Functions:

• { param => fun(param) }

• (param: T) => fun(param)

6

Page 27: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Scala Primer

• Local variables: val x = fun(arg) // type inference

• Functions:

• { param => fun(param) }

• (param: T) => fun(param)

• Function type: T => S or (T, S) => U

6

Page 28: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Scala Primer

• Local variables: val x = fun(arg) // type inference

• Functions:

• { param => fun(param) }

• (param: T) => fun(param)

• Function type: T => S or (T, S) => U

• Methods: def meth(x: T, y: S): R = { .. }

6

Page 29: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Scala Primer

• Local variables: val x = fun(arg) // type inference

• Functions:

• { param => fun(param) }

• (param: T) => fun(param)

• Function type: T => S or (T, S) => U

• Methods: def meth(x: T, y: S): R = { .. }

• Classes: class C extends D { .. }

6

Page 30: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Scala Primer (2)

7

Page 31: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Scala Primer (2)

7

• Generics:

Page 32: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Scala Primer (2)

7

• Generics:

• class C[T] { var fld: T = _ ; .. }

Page 33: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Scala Primer (2)

7

• Generics:

• class C[T] { var fld: T = _ ; .. }

• def convert[T](obj: T): Result = ..

Page 34: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Scala Primer (2)

7

• Generics:

• class C[T] { var fld: T = _ ; .. }

• def convert[T](obj: T): Result = ..

• Pattern matching:

Page 35: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Scala Primer (2)

7

• Generics:

• class C[T] { var fld: T = _ ; .. }

• def convert[T](obj: T): Result = ..

• Pattern matching:

• case class Person(name: String, age: Int)

Page 36: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Scala Primer (2)

7

• Generics:

• class C[T] { var fld: T = _ ; .. }

• def convert[T](obj: T): Result = ..

• Pattern matching:

• case class Person(name: String, age: Int)

• val isAdult = p match { case Person(_, a) => a >= 18 case Alien(_, _) => false }

Page 37: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Example

• Common task:

• Convert object to JSON

• Send HTTP request containing JSON

8

Page 38: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Example

• Common task:

• Convert object to JSON

• Send HTTP request containing JSON

8

import scala.util.parsing.json._

def convert[T](obj: T): Future[JSONType] def sendReq(json: JSONType): Future[JSONType]

Page 39: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Example

• Common task:

• Convert object to JSON

• Send HTTP request containing JSON

8

import scala.util.parsing.json._

def convert[T](obj: T): Future[JSONType] def sendReq(json: JSONType): Future[JSONType]

Page 40: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Example

• Common task:

• Convert object to JSON

• Send HTTP request containing JSON

8

import scala.util.parsing.json._

def convert[T](obj: T): Future[JSONType] def sendReq(json: JSONType): Future[JSONType]

Ousterhout et al. Making sense of performance in data analytics frameworks. NSDI ’15

Page 41: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Callbacks

• How to respond to asynchronous completion event?

➟ Register callback

9

Page 42: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Callbacks

• How to respond to asynchronous completion event?

➟ Register callback

9

val person = Person(“Tim”, 25)

val fut: Future[JSONType] = convert(person)

fut.foreach { json => val resp: Future[JSONType] = sendReq(json) .. }

Page 43: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Exceptions

• Serialization to JSON may fail at runtime

• Closure passed to foreach not executed in this case

• How to handle asynchronous exceptions?

10

Page 44: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Exceptions

• Serialization to JSON may fail at runtime

• Closure passed to foreach not executed in this case

• How to handle asynchronous exceptions?

10

val fut: Future[JSONType] = convert(person)

fut.onComplete { case Success(json) => val resp: Future[JSONType] = sendReq(json) case Failure(e) => e.printStackTrace() }

Page 45: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Partial Functions

11

{ case Success(json) => .. case Failure(e) => .. }

Page 46: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Partial Functions

11

{ case Success(json) => .. case Failure(e) => .. }

… creates an instance of PartialFunction[T, R]:

Page 47: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Partial Functions

11

{ 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 48: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Type of Partial Functions

• Partial functions have a type PartialFunction[A, B]

• PartialFunction[A, B] is a subtype of Function1[A, B]

12

Page 49: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Type of Partial Functions

• Partial functions have a type PartialFunction[A, B]

• PartialFunction[A, B] is a subtype of Function1[A, B]

12

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] .. }

Page 50: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Type of Partial Functions

• Partial functions have a type PartialFunction[A, B]

• PartialFunction[A, B] is a subtype of Function1[A, B]

12

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!

Page 51: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Success and Failure

13

package scala.util

abstract class Try[+T]

case class Success[+T](v: T) extends Try[T]

case class Failure[+T](e: Throwable) extends Try[T]

Page 52: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Nested Exceptions

➟ Exception handling tedious and not compositional:

14

Page 53: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Nested Exceptions

➟ Exception handling tedious and not compositional:

14

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 54: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Failed Futures

15

Page 55: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Failed Futures

• Future[T] is completed with Try[T], i.e., with success or failure

15

Page 56: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Failed Futures

• Future[T] is completed with Try[T], i.e., with success or failure

• Combinators enable compositional failure handling

15

Page 57: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Failed Futures

• Future[T] is completed with Try[T], i.e., with success or failure

• Combinators enable compositional failure handling

• Example:

15

Page 58: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Failed Futures

• Future[T] is completed with Try[T], i.e., with success or failure

• Combinators enable compositional failure handling

• Example:

15

val resp: Future[JSONType] = sendReq(json) val processed = resp.map { jsonResp => .. // happy path }

Page 59: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Failed Futures

• Future[T] is completed with Try[T], i.e., with success or failure

• Combinators enable compositional failure handling

• Example:

15

val resp: Future[JSONType] = sendReq(json) val processed = resp.map { jsonResp => .. // happy path }

Encapsulates failure

Page 60: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Map Combinator

16

Page 61: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Map Combinator• Creates a new future by applying a function to the

successful result of the receiver future

16

Page 62: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

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

16

Page 63: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

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, pending future is also completed with e

16

Page 64: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

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, pending future is also completed with e

16

abstract class Future[+T] extends Awaitable[T] {

def map[S](f: T => S)(implicit ..): Future[S]

// .. }

Page 65: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Future Composition

17

val fut: Future[JSONType] = convert(person)

val processed = fut.map { json => val resp: Future[JSONType] = sendReq(json) resp.map { jsonResp => .. // happy path } }

Page 66: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Future Composition

17

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

Page 67: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Future Composition

17

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 68: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Future Pipelining

18

val fut: Future[JSONType] = convert(person)

val processed = fut.flatMap { json => val resp: Future[JSONType] = sendReq(json) resp.map { jsonResp => .. // happy path } }

Page 69: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Future Pipelining

18

val fut: Future[JSONType] = convert(person)

val processed = fut.flatMap { json => val resp: Future[JSONType] = sendReq(json) resp.map { jsonResp => .. // happy path } }

Page 70: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Future Pipelining

Future pipelining: the result of the inner future (result of

map) determines the result of the outer future (processed)

18

val fut: Future[JSONType] = convert(person)

val processed = fut.flatMap { json => val resp: Future[JSONType] = sendReq(json) resp.map { jsonResp => .. // happy path } }

Page 71: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

FlatMap Combinator

19

Page 72: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

FlatMap Combinator• Creates a new future by applying a function to the

successful result of the receiver future

19

Page 73: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

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

19

Page 74: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

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

19

Page 75: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

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, pending future is also completed with e

19

Page 76: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

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, pending future is also completed with e

19

def flatMap[S](f: T => Future[S])(implicit ..): Future[S]

Page 77: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Creating Futures

20

Page 78: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Creating Futures• Futures are created based on (a) computations, (b) events,

or (c) combinations thereof

20

Page 79: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Creating Futures• Futures are created based on (a) computations, (b) events,

or (c) combinations thereof

• Creating computation-based futures:

20

object Future {

def apply[T](body: => T)(implicit ..): Future[T]

}

Page 80: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Creating Futures• Futures are created based on (a) computations, (b) events,

or (c) combinations thereof

• Creating computation-based futures:

20

object Future {

def apply[T](body: => T)(implicit ..): Future[T]

}Singleton object

Page 81: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Creating Futures• Futures are created based on (a) computations, (b) events,

or (c) combinations thereof

• Creating computation-based futures:

20

object Future {

def apply[T](body: => T)(implicit ..): Future[T]

}Singleton object

“Code block” with result type T

Page 82: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Creating Futures• Futures are created based on (a) computations, (b) events,

or (c) combinations thereof

• Creating computation-based futures:

20

object Future {

def apply[T](body: => T)(implicit ..): Future[T]

}Singleton object

“Code block” with result type T

“Unrelated” to the singleton

object!

Page 83: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Futures: Example

21

Page 84: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Futures: Example

21

val firstGoodDeal = Future { usedCars.find(car => isGoodDeal(car)) }

Page 85: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Futures: Example

21

val firstGoodDeal = Future { usedCars.find(car => isGoodDeal(car)) }

val firstGoodDeal = Future.apply({ usedCars.find(car => isGoodDeal(car)) })

Short syntax for:

Page 86: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Futures: Example

21

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)) })

Page 87: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Futures: Example

21

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 88: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Creating Futures: Operationally

22

Page 89: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Creating Futures: Operationally• Invoking the shown factory method creates a task object

encapsulating the computation

22

Page 90: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

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

22

Page 91: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

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 an object capable of executing tasks, typically using a thread pool

22

Page 92: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

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 an object capable of executing tasks, typically using a thread pool

• Future tasks are submitted to the current implicit execution context

22

def apply[T](body: => T)(implicit executor: ExecutionContext): Future[T]

Page 93: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Implicit Execution ContextsImplicit parameter requires selecting a execution context

23

Page 94: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Implicit Execution ContextsImplicit parameter requires selecting a execution context

23

Welcome to Scala version 2.11.6 (Java HotSpot(TM) ..). Type in expressions to have them evaluated. Type :help for more information.

scala> import scala.concurrent._ import scala.concurrent._

scala> val fut = Future { 40 + 2 }

Page 95: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Implicit Execution ContextsImplicit parameter requires selecting a execution context

23

<console>:10: error: Cannot find an implicit ExecutionContext. You might pass

Welcome to Scala version 2.11.6 (Java HotSpot(TM) ..). Type in expressions to have them evaluated. Type :help for more information.

scala> import scala.concurrent._ import scala.concurrent._

scala> val fut = Future { 40 + 2 }

Page 96: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Implicit Execution ContextsImplicit parameter requires selecting a execution context

23

???

<console>:10: error: Cannot find an implicit ExecutionContext. You might pass

Welcome to Scala version 2.11.6 (Java HotSpot(TM) ..). Type in expressions to have them evaluated. Type :help for more information.

scala> import scala.concurrent._ import scala.concurrent._

scala> val fut = Future { 40 + 2 }

Page 97: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Implicit Execution ContextsImplicit parameter requires selecting a execution context

23

<console>:10: error: Cannot find an implicit ExecutionContext. You might pass

Welcome to Scala version 2.11.6 (Java HotSpot(TM) ..). Type in expressions to have them evaluated. Type :help for more information.

scala> import scala.concurrent._ import scala.concurrent._

scala> val fut = Future { 40 + 2 } But…

Page 98: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Implicit Execution ContextsImplicit parameter requires selecting a execution context

23

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 version 2.11.6 (Java HotSpot(TM) ..). Type in expressions to have them evaluated. Type :help for more information.

scala> import scala.concurrent._ import scala.concurrent._

scala> val fut = Future { 40 + 2 }

Page 99: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Promise

24

Page 100: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Promise

Main purpose: create futures for non-lexically-scoped asynchronous code

24

Page 101: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Promise

Main purpose: create futures for non-lexically-scoped asynchronous code

24

Example

Function for creating a Future that is completed with value after delay milliseconds

Page 102: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Promise

Main purpose: create futures for non-lexically-scoped asynchronous code

24

def after[T](delay: Long, value: T): Future[T]

Example

Function for creating a Future that is completed with value after delay milliseconds

Page 103: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

“after”, Version 1

25

def after1[T](delay: Long, value: T) = Future { Thread.sleep(delay) value }

Page 104: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

“after”, Version 1

26

How does it behave?

Page 105: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

“after”, Version 1

26

assert(Runtime.getRuntime() .availableProcessors() == 8)

for (_ <- 1 to 8) yield after1(1000, true)

val later = after1(1000, true)

How does it behave?

Page 106: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

“after”, Version 1

26

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?

Page 107: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

“after”, Version 1

26

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 108: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Promise

27

object Promise { def apply[T](): Promise[T] }

Page 109: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Promise

27

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 110: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

“after”, Version 2

28

def after2[T](delay: Long, value: T) = { val promise = Promise[T]() timer.schedule(new TimerTask { def run(): Unit = promise.success(value) }, delay) promise.future }

Page 111: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

“after”, Version 2

28

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 112: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

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 and 2.11

29

Page 113: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

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

30

Page 114: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Programming Model

Basis: suspendible computations

31

Page 115: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Programming Model

Basis: suspendible computations

• async { .. } — delimit suspendible computation

31

Page 116: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Programming Model

Basis: suspendible computations

• async { .. } — delimit suspendible computation

• await(future) — suspend computation until

future is completed

31

Page 117: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Async

32

Page 118: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Async

32

object Async {

def async[T](body: => T): Future[T]

def await[T](future: Future[T]): T

}

Page 119: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Example

33

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 120: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Futures vs. Async

• “Futures and Async: When to Use Which?”, Scala Days 2014, Berlin

• Video:

34

https://www.parleys.com/tutorial/futures-async-when-use-which

Page 121: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

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

35

1 http://tc39.github.io/ecmascript-asyncawait/

Page 122: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

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?

36

Page 123: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

The Actor Model

37

Page 124: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

The Actor Model• Model of concurrent computation whose universal primitive is

the “actor” [Hewitt et al. ’73]

37

Page 125: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

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

37

Page 126: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

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

37

Related to active objects

Page 127: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

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

37

Related to active objects

Page 128: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

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

37

Related to active objects

Page 129: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

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

37

Related to active objects

Page 130: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Example

38

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(",") } } }

Page 131: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Example

38

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 132: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

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

39

class ActorWithTasks(tasks: List[Task]) extends Actor { def receive = { case TaskFor(workers) => // send `tasks` to `workers` case Stop => // stop `self` } }

Page 133: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

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

40

case class TaskFor(workers: List[ActorRef]) case object Stop

Page 134: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

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

41

val system = ActorSystem(“test-system”) val actor1: ActorRef = system.actorOf[ActorWithTasks]

actor1 ! TaskFor(List()) // async message send

Page 135: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Why Actors?

42

Page 136: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Why Actors?Reason 1: simplified concurrency

42

Page 137: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Why Actors?Reason 1: simplified concurrency

• “Share nothing”: strong isolation of actors ➟ no race conditions

42

Page 138: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

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

42

Page 139: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

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

42

“Macro-step semantics”

Page 140: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

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

42

“Macro-step semantics”

Page 141: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

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

42

“Macro-step semantics”

Page 142: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Why Actors? (cont’d)

43

Page 143: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Why Actors? (cont’d)Reason 2: actors model reality of distributed systems

43

Page 144: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Why Actors? (cont’d)Reason 2: actors model reality of distributed systems

• Message sends truly asynchronous

43

Page 145: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Why Actors? (cont’d)Reason 2: actors model reality of distributed systems

• Message sends truly asynchronous

• Message reception not guaranteed

43

Page 146: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

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

43

Page 147: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

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

43

Page 148: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

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

43

Page 149: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Summary

44

Page 150: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Summary

• Concurrency benefits from growable languages

44

Page 151: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Summary

• Concurrency benefits from growable languages

• Futures and promises a versatile abstraction for single, asynchronous events

44

Page 152: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

Philipp Haller

Summary

• Concurrency benefits from growable languages

• Futures and promises a versatile abstraction for single, asynchronous events

• Supported by async/await

44

Page 153: Futures, Actors, and Streamsstg-tud.github.io/ctbd/2016/CTBD_09_futures_actors.pdf · Futures, Actors, and Streams. Philipp Haller Programming a Concurrent World ... • Contributed

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

44