Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Safe and Scalable Concurrent Programming in Scala

3b84657fdb075382e3781310ca8a9a70?s=47 Philipp Haller
December 01, 2016
120

Safe and Scalable Concurrent Programming in Scala

3b84657fdb075382e3781310ca8a9a70?s=128

Philipp Haller

December 01, 2016
Tweet

Transcript

  1. Safe and Scalable Concurrent Programming in Scala 1 Philipp Haller

    10th Multicore Day 2016 Stockholm, Sweden December 1st, 2016 KTH Royal Institute of Technology Sweden
  2. Programming a Concurrent World 2

  3. Programming a Concurrent World • How to compose programs handling

    2
  4. Programming a Concurrent World • How to compose programs handling

    • asynchronous events? 2
  5. Programming a Concurrent World • How to compose programs handling

    • asynchronous events? • streams of asynchronous events? 2
  6. Programming a Concurrent World • How to compose programs handling

    • asynchronous events? • streams of asynchronous events? • distributed events? 2
  7. Programming a Concurrent World • How to compose programs handling

    • asynchronous events? • streams of asynchronous events? • distributed events? ➟ Programming abstractions for concurrency! 2
  8. What is Scala? • Integrates object-oriented and functional programming •

    Statically typed • Lightweight syntax (via type inference) • Compilation targets: JVM, JavaScript • Fully interoperable with Java and JavaScript (no glue code) • As fast as Java • Open source development backed by:
 EPFL, Lightbend Inc., and Scala Center (non-profit) 3
  9. What is Scala? • Integrates object-oriented and functional programming •

    Statically typed • Lightweight syntax (via type inference) • Compilation targets: JVM, JavaScript • Fully interoperable with Java and JavaScript (no glue code) • As fast as Java • Open source development backed by:
 EPFL, Lightbend Inc., and Scala Center (non-profit) 3 Advisory board members include Goldman Sachs, IBM, SAP, and Verizon
  10. Rankings: RedMonk Q316 4 Source: http://redmonk.com/sogrady/2016/07/20/language-rankings-6-16/

  11. Rankings: RedMonk Q316 4 Source: http://redmonk.com/sogrady/2016/07/20/language-rankings-6-16/ # of tags on

    StackOverflow
  12. Rankings: RedMonk Q316 4 Source: http://redmonk.com/sogrady/2016/07/20/language-rankings-6-16/ # of tags on

    StackOverflow # of projects on GitHub
  13. Rankings: RedMonk Q316 4 Source: http://redmonk.com/sogrady/2016/07/20/language-rankings-6-16/ # of tags on

    StackOverflow # of projects on GitHub
  14. Rankings: RedMonk Q316 (zoomed) 5 Source: http://redmonk.com/sogrady/2016/07/20/language-rankings-6-16/

  15. Concurrent Programming in Scala 6

  16. Example Image data 7

  17. Example Image data apply filter 7

  18. Example Image data apply filter 7

  19. Example Image data apply filter Image processing pipeline: filter 1

    filter 2 7
  20. Futures 8 val imgData: Buffer = .. val filter: Filter

    = .. val futImgData = Future { filter.applyTo(imgData) } futImgData.foreach { imgDataOut => // .. }
  21. Futures: Two Filters 9 val futImgDataOut1 = Future { filter1.applyTo(imgData)

    } val futImgDataOut2 = futImgDataOut1.map { imgDataOut1 => filter2.applyTo(imgDataOut1) } futImgDataOut2.foreach { imgDataOut2 => // .. }
  22. Futures: Composition 10 def applyFilter(imgData: Buffer, filter: Filter): Future[Buffer] =

    .. val futImgDataOut1 = applyFilter(imgData, filter1) val futImgDataOut2 = futImgDataOut1.flatMap { imgDataOut1 => applyFilter(imgDataOut1, filter2) } futImgDataOut2.foreach { imgDataOut2 => // .. }
  23. Futures: Composition 10 def applyFilter(imgData: Buffer, filter: Filter): Future[Buffer] =

    .. val futImgDataOut1 = applyFilter(imgData, filter1) val futImgDataOut2 = futImgDataOut1.flatMap { imgDataOut1 => applyFilter(imgDataOut1, filter2) } futImgDataOut2.foreach { imgDataOut2 => // .. } How to process many images efficiently?
  24. Actors 11 class Stage(filter: Filter, next: ActorRef) extends Actor {

    def receive = { case Process(imgData) => val imgDataOut = filter.applyTo(imgData) next ! Process(imgDataOut) case Stop() => context.stop(self) } }
  25. Is this all built into Scala? 12

  26. Futures 13 val imgData: Buffer = .. val filter: Filter

    = .. val futImgData = Future { filter.applyTo(imgData) } futImgData.foreach { imgDataOut => // .. }
  27. Futures 14 val imgData: Buffer = .. val filter: Filter

    = .. val futImgData: Future[Buffer] = Future.apply[Buffer]({ filter.applyTo(imgData) }) futImgData.foreach { imgDataOut => // .. }
  28. Futures Creating a future: 15 object Future { def apply[T](body:

    => T): Future[T] }
  29. Futures Creating a future: 15 object Future { def apply[T](body:

    => T): Future[T] } Singleton object
  30. Futures Creating a future: 15 object Future { def apply[T](body:

    => T): Future[T] } Singleton object Generic type parameter
  31. Futures Creating a future: 15 object Future { def apply[T](body:

    => T): Future[T] } Singleton object Generic type parameter “Code block” with result type T
  32. Actors: Akka Library 16 class Stage(filter: Filter, next: ActorRef) extends

    Actor { def receive = { case Process(imgData) => val imgDataOut = filter.applyTo(imgData) next ! Process(imgDataOut) case Stop() => context.stop(self) } }
  33. Actors: Akka Library 16 class Stage(filter: Filter, next: ActorRef) extends

    Actor { def receive = { case Process(imgData) => val imgDataOut = filter.applyTo(imgData) next ! Process(imgDataOut) case Stop() => context.stop(self) } } Pattern matching
  34. Actors: Akka Library 16 class Stage(filter: Filter, next: ActorRef) extends

    Actor { def receive = { case Process(imgData) => val imgDataOut = filter.applyTo(imgData) next ! Process(imgDataOut) case Stop() => context.stop(self) } } Pattern matching Case class
  35. Actors: Akka Library 16 class Stage(filter: Filter, next: ActorRef) extends

    Actor { def receive = { case Process(imgData) => val imgDataOut = filter.applyTo(imgData) next ! Process(imgDataOut) case Stop() => context.stop(self) } } Pattern matching Infix call of “!” method Case class
  36. Concurrent Programming Models as Libraries • Scala = “Scalable Language”

    • cf. Guy Steele. Growing a Language. OOPSLA ’98 keynote • Concurrent programming models as libraries • Based on shared-memory threads built into underlying virtual machine • Flexible extension and adaptation • Reuse of compilers, debuggers, and IDEs 17
  37. Concurrent Programming Models as Libraries • Scala = “Scalable Language”

    • cf. Guy Steele. Growing a Language. OOPSLA ’98 keynote • Concurrent programming models as libraries • Based on shared-memory threads built into underlying virtual machine • Flexible extension and adaptation • Reuse of compilers, debuggers, and IDEs 17 Do not have to guess the answer to the question: Which concurrency model is going to “win”?
  38. Experience • Authored or co-authored: • Scala Actors (2006) •

    Scala Joins (2008) • Scala futures (2012) • FlowPools (2012) • Scala Async (2013) • Contributions to Akka, Akka.js projects at Typesafe 18 Haller and Sommers Artima Press, 2012
  39. Experience • Authored or co-authored: • Scala Actors (2006) •

    Scala Joins (2008) • Scala futures (2012) • FlowPools (2012) • Scala Async (2013) • Contributions to Akka, Akka.js projects at Typesafe 18 Haller and Sommers Artima Press, 2012 Production use at Twitter, The Guardian and others
  40. Experience • Authored or co-authored: • Scala Actors (2006) •

    Scala Joins (2008) • Scala futures (2012) • FlowPools (2012) • Scala Async (2013) • Contributions to Akka, Akka.js projects at Typesafe 18 Haller and Sommers Artima Press, 2012 Production use at Twitter, The Guardian and others Production use at LinkedIn, The Huffington Post and others
  41. Experience • Authored or co-authored: • Scala Actors (2006) •

    Scala Joins (2008) • Scala futures (2012) • FlowPools (2012) • Scala Async (2013) • Contributions to Akka, Akka.js projects at Typesafe 18 Haller and Sommers Artima Press, 2012 Production use at Twitter, The Guardian and others Production use at Morgan Stanley, Gawker and others Production use at LinkedIn, The Huffington Post and others
  42. Experience • Authored or co-authored: • Scala Actors (2006) •

    Scala Joins (2008) • Scala futures (2012) • FlowPools (2012) • Scala Async (2013) • Contributions to Akka, Akka.js projects at Typesafe 18 Haller and Sommers Artima Press, 2012 Production use at Twitter, The Guardian and others Production use at Morgan Stanley, Gawker and others Production use at LinkedIn, The Huffington Post and others The programming-models-as-libraries approach has been successful in Scala!
  43. Problem • Problem: Scala cannot ensure concurrency safety for library-based

    concurrency abstractions • This also applies to Java, C++, and most other widely-used programming languages 19
  44. Revisiting the Example Image data apply filter Image processing pipeline:

    filter 1 filter 2 20 Pipeline stages run concurrently
  45. Implementation 21

  46. Implementation • Assumptions: • Main memory expensive (image data large)

    21
  47. Implementation • Assumptions: • Main memory expensive (image data large)

    • Approach for high performance: • In-place update of image buffers • Pass mutable buffers by-reference 21
  48. Problem: Data Races Easy to produce data races: 1. Stage

    1 sends a reference to a buffer to stage 2 2. Following the send, both stages have a reference to the same buffer 3. Stages can concurrently access the buffer 22
  49. Preventing Data Races 23

  50. Preventing Data Races • Approach: safe transfer of ownership •

    Sending stage loses ownership • Type system prevents sender from accessing transferred objects 23
  51. Preventing Data Races • Approach: safe transfer of ownership •

    Sending stage loses ownership • Type system prevents sender from accessing transferred objects • Advantages: • No run-time overhead • Errors caught at compile time 23
  52. Ownership Transfer in Scala 24

  53. Ownership Transfer in Scala • Enter LaCasa: affine references for

    Scala 24
  54. Ownership Transfer in Scala • Enter LaCasa: affine references for

    Scala • “Transferable” references 24
  55. Ownership Transfer in Scala • Enter LaCasa: affine references for

    Scala • “Transferable” references • At most one owner per affine reference 24
  56. Ownership Transfer in Scala • Enter LaCasa: affine references for

    Scala • “Transferable” references • At most one owner per affine reference • LaCasa combines two concepts: 24
  57. Ownership Transfer in Scala • Enter LaCasa: affine references for

    Scala • “Transferable” references • At most one owner per affine reference • LaCasa combines two concepts: • Access permissions 24
  58. Ownership Transfer in Scala • Enter LaCasa: affine references for

    Scala • “Transferable” references • At most one owner per affine reference • LaCasa combines two concepts: • Access permissions • Encapsulated boxes 24
  59. Boxes • Boxes are encapsulated • Boxes must be opened

    for access 25
  60. Boxes • Boxes are encapsulated • Boxes must be opened

    for access mkBox[Message] { packed => implicit val access = packed.access val box = packed.box box open { msg => msg.arr = Array(1, 2, 3, 4) } } 25
  61. Boxes • Boxes are encapsulated • Boxes must be opened

    for access mkBox[Message] { packed => implicit val access = packed.access val box = packed.box box open { msg => msg.arr = Array(1, 2, 3, 4) } } Requires implicit access permission 25
  62. Boxes • Boxes are encapsulated • Boxes must be opened

    for access mkBox[Message] { packed => implicit val access = packed.access val box = packed.box box open { msg => msg.arr = Array(1, 2, 3, 4) } } 25
  63. Ownership Transfer mkBox[Message] { packed => implicit val access =

    packed.access val box = packed.box … someActor.send(box) { // `access` unavailable … } } 26
  64. Practical Evaluation Empirical study of popular open source projects 27

    Project #classes/traits #ocap (%) #dir. insec. (%) Scala stdlib 1,505 644 (43%) 212/861 (25%) Signal/Collect 236 159 (67%) 60/77 (78%) GeoTrellis -engine 190 40 (21%) 124/150 (83%) -raster 670 233 (35%) 325/437 (74%) -spark 326 101 (31%) 167/225 (74%) Total 2,927 1,177 (40%) 888/1,750 (51%)
  65. Practical Evaluation Empirical study of popular open source projects 27

    Project #classes/traits #ocap (%) #dir. insec. (%) Scala stdlib 1,505 644 (43%) 212/861 (25%) Signal/Collect 236 159 (67%) 60/77 (78%) GeoTrellis -engine 190 40 (21%) 124/150 (83%) -raster 670 233 (35%) 325/437 (74%) -spark 326 101 (31%) 167/225 (74%) Total 2,927 1,177 (40%) 888/1,750 (51%) > 75’000 LOC on GitHub
  66. Practical Evaluation Empirical study of popular open source projects 27

    Project #classes/traits #ocap (%) #dir. insec. (%) Scala stdlib 1,505 644 (43%) 212/861 (25%) Signal/Collect 236 159 (67%) 60/77 (78%) GeoTrellis -engine 190 40 (21%) 124/150 (83%) -raster 670 233 (35%) 325/437 (74%) -spark 326 101 (31%) 167/225 (74%) Total 2,927 1,177 (40%) 888/1,750 (51%) > 75’000 LOC on GitHub
  67. Practical Evaluation Empirical study of popular open source projects 27

    Project #classes/traits #ocap (%) #dir. insec. (%) Scala stdlib 1,505 644 (43%) 212/861 (25%) Signal/Collect 236 159 (67%) 60/77 (78%) GeoTrellis -engine 190 40 (21%) 124/150 (83%) -raster 670 233 (35%) 325/437 (74%) -spark 326 101 (31%) 167/225 (74%) Total 2,927 1,177 (40%) 888/1,750 (51%) “Ocap”: classes reusable without change > 75’000 LOC on GitHub
  68. LaCasa: Types for Safe Concurrency in Scala 28

  69. LaCasa: Types for Safe Concurrency in Scala • Ensure data-race

    safety statically via lightweight types • Sound integration with full Scala language • Minimize effort to reuse existing code:
 binary conformance check (yes/no) 28
  70. LaCasa: Types for Safe Concurrency in Scala • Ensure data-race

    safety statically via lightweight types • Sound integration with full Scala language • Minimize effort to reuse existing code:
 binary conformance check (yes/no) • Recent paper:
 Haller and Loiko. LaCasa: Lightweight Affinity and Object Capabilities in Scala. OOPSLA 2016 28
  71. LaCasa: Types for Safe Concurrency in Scala • Ensure data-race

    safety statically via lightweight types • Sound integration with full Scala language • Minimize effort to reuse existing code:
 binary conformance check (yes/no) • Recent paper:
 Haller and Loiko. LaCasa: Lightweight Affinity and Object Capabilities in Scala. OOPSLA 2016 • Ongoing:
 Empirical study on open source code corpus 28
  72. LaCasa: Types for Safe Concurrency in Scala • Ensure data-race

    safety statically via lightweight types • Sound integration with full Scala language • Minimize effort to reuse existing code:
 binary conformance check (yes/no) • Recent paper:
 Haller and Loiko. LaCasa: Lightweight Affinity and Object Capabilities in Scala. OOPSLA 2016 • Ongoing:
 Empirical study on open source code corpus 28 Open source implementation: https://github.com/phaller/lacasa
  73. Conclusion 29

  74. Conclusion • Scala enables new concurrent programming methods 29

  75. Conclusion • Scala enables new concurrent programming methods • Scala

    enables library extensions providing new concurrent programming models • Building on concurrency support of underlying runtime platform 29
  76. Conclusion • Scala enables new concurrent programming methods • Scala

    enables library extensions providing new concurrent programming models • Building on concurrency support of underlying runtime platform • Scalability and performance enable wide use in large- scale production systems 29
  77. Conclusion • Scala enables new concurrent programming methods • Scala

    enables library extensions providing new concurrent programming models • Building on concurrency support of underlying runtime platform • Scalability and performance enable wide use in large- scale production systems • Lightweight type system extensions are being developed to ensure concurrency safety 29
  78. Conclusion • Scala enables new concurrent programming methods • Scala

    enables library extensions providing new concurrent programming models • Building on concurrency support of underlying runtime platform • Scalability and performance enable wide use in large- scale production systems • Lightweight type system extensions are being developed to ensure concurrency safety 29 Thank you!