70
Concurrency In Practice erik rozendaal A Case Study Friday, May 25, 12

Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

  • Upload
    others

  • View
    3

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Concurrency In Practice

erik rozendaal

A Case Study

Friday, May 25, 12

Page 2: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Introduction

Friday, May 25, 12

Page 3: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

who am i?

Erik Rozendaal, software developer, etc.

email: ! [email protected]: @erozendaal

Friday, May 25, 12

Page 4: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

who am i?

Erik Rozendaal, software developer, etc.

email: ! [email protected]: @erozendaal

(... and I did not write that CQRS framework)

Friday, May 25, 12

Page 5: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

RPKI Validator

• Open Source (BSD license)

• Developed at the RIPE NCC (www.ripe.net)

• Aimed at Internet router administrators

• http://www.ripe.net/lir-services/resource-management/certification/tools-and-resources

ScalazFriday, May 25, 12

Page 6: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

• The RIPE NCC is one of five Regional Internet Registries (RIRs) providing Internet resource allocations, registration services and coordination activities that support the operation of the Internet globally.

• Basically, helps ensure that every Internet Address is uniquely distributed and the Internet keeps working

Friday, May 25, 12

Page 7: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Internet Routing 101

AS 9

AS 23

AS 3

AS 4

Friday, May 25, 12

Page 8: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Internet Routing 101

AS 9

AS 23

AS 3

AS 4

Where is 172.16.0.1?

Friday, May 25, 12

Page 9: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Internet Routing 101

AS 9

AS 23

AS 3

AS 4

Where is 172.16.0.1?

Send everything starting with 172.16 to me!

Friday, May 25, 12

Page 10: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Internet Routing 101

AS 9

AS 23

AS 3

AS 4

Where is 172.16.0.1?

Send everything starting with 172.16 to me!

Can I verify this?

Friday, May 25, 12

Page 11: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Internet Routing 101

AS 9

AS 23

AS 3

AS 4

Where is 172.16.0.1?

Send everything starting with 172.16 to me!

Can I verify this?

Here’s my certified Route Origin

Authorization (ROA)

Friday, May 25, 12

Page 12: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Internet Resource PKI (RPKI)• Distributed database of cryptographically signed statements

about resources

• IETF standard

• Rooted at the five Regional Internet Registries (RIRs)

• AfriNIC - Africa

• ARIN - United States, Canada, ...

• APNIC - Asia, Australia, New Zealand, ...

• LACNIC - Latin America, ...

• RIPE NCC - Europe, Russia, Middle East, ...

Friday, May 25, 12

Page 13: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Big Picture

RPKI Validator

NetworkRouter

Routing Information

NetworkRouter

NetworkRouter

NetworkRouter

RPKI Repository

RPKIRepository

RPKIRepository

rsync

RTR

HTTP

Friday, May 25, 12

Page 14: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

demo

Friday, May 25, 12

Page 15: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Immutability

Friday, May 25, 12

Page 16: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Immutability

• An immutable object is an object whose state cannot be modified after it is created

• Immutable objects can be safely shared between multiple threads

• Scala makes it easy to define immutable objects and defaults to full set of immutable collection types

Friday, May 25, 12

Page 17: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Immutable collections?

Friday, May 25, 12

Page 18: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Immutable collections?def add(x: Int, y: Int) = { var result = 0 result += x result += y result}

Friday, May 25, 12

Page 19: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Immutable collections?def add(x: Int, y: Int) = { var result = 0 result += x result += y result}

def concat(x: List, y: List) = { val result = new ArrayList() result.addAll(x) result.addAll(y) result}

Friday, May 25, 12

Page 20: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Immutable collections?def add(x: Int, y: Int) = { var result = 0 result += x result += y result}

def concat(x: List, y: List) = { val result = new ArrayList() result.addAll(x) result.addAll(y) result}

def add(x: Int, y: Int) = x + y

Friday, May 25, 12

Page 21: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Immutable collections?def add(x: Int, y: Int) = { var result = 0 result += x result += y result}

def concat(x: List, y: List) = { val result = new ArrayList() result.addAll(x) result.addAll(y) result}

def add(x: Int, y: Int) = x + y

def concat(x: List, y: List) = x ++ y

Friday, May 25, 12

Page 22: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Immutable collections?def add(x: Int, y: Int) = { var result = 0 result += x result += y result}

def concat(x: List, y: List) = { val result = new ArrayList() result.addAll(x) result.addAll(y) result}

def add(x: Int, y: Int) = x + y

def concat(x: List, y: List) = x ++ y

Immutability is the difference between java.util.Calendar and org.joda.time.DateTime

Friday, May 25, 12

Page 23: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Memory Imagecase class MemoryImage( trustAnchors : Vector[TrustAnchor], validatedObjects: Vector[ValidatedObject], filters : Vector[Filter], whitelist : Vector[WhitelistEntry], version : Int = 0)

case class TrustAnchor( locator : TrustAnchorLocator, status : ProcessingStatus, enabled : Boolean = true)

// Etc.

Friday, May 25, 12

Page 24: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Memory Image

• Initially access was controlled using a single AtomicReference containing the most recent instance

• http://martinfowler.com/bliki/MemoryImage.html

Friday, May 25, 12

Page 25: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Memory Image Implementationobject MemoryImage { private[this] val memoryImage = new AtomicReference(MemoryImage(...))

Friday, May 25, 12

Page 26: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Memory Image Implementationobject MemoryImage { private[this] val memoryImage = new AtomicReference(MemoryImage(...))

// Reading def get: MemoryImage = memoryImage.get

Friday, May 25, 12

Page 27: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Memory Image Implementationobject MemoryImage { private[this] val memoryImage = new AtomicReference(MemoryImage(...))

// Reading def get: MemoryImage = memoryImage.get

// Updating @tailrec def modify(f: MemoryImage => MemoryImage): MemoryImage = { val current = memoryImage.get val updated = f(current) if (memoryImage.compareAndSet(current, updated)) updated else modify(f) // Retry }}

Friday, May 25, 12

Page 28: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Memory Image Implementationobject MemoryImage { private[this] val memoryImage = new AtomicReference(MemoryImage(...))

// Reading def get: MemoryImage = memoryImage.get

// Updating @tailrec def modify(f: MemoryImage => MemoryImage): MemoryImage = { val current = memoryImage.get val updated = f(current) if (memoryImage.compareAndSet(current, updated)) updated else modify(f) // Retry }}

// Example updateMemoryImage.modify { memoryImage => memoryImage.copy(filters = /* updated filters */)}

Friday, May 25, 12

Page 29: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Atomic Reference

• Fast and lock-free!

• Callback to modify may be run multiple times, so avoid side-effects

Friday, May 25, 12

Page 30: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Atomic Reference

• Fast and lock-free!

• Callback to modify may be run multiple times, so avoid side-effects

• ... but AtomicReferences do not compose, hurting modularity

Friday, May 25, 12

Page 31: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Atomic Reference

• Fast and lock-free!

• Callback to modify may be run multiple times, so avoid side-effects

• ... but AtomicReferences do not compose, hurting modularity

• Try updating two AtomicReferences atomically...

Friday, May 25, 12

Page 32: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Atomic Reference

• Fast and lock-free!

• Callback to modify may be run multiple times, so avoid side-effects

• ... but AtomicReferences do not compose, hurting modularity

• Try updating two AtomicReferences atomically...

• (the same is true for locks)

Friday, May 25, 12

Page 33: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Software Transactional Memory

• Take the idea of a database transaction (ACID) and apply it to your in-memory data structures (ACI)

• Composable: bigger transactions can be created from existing, smaller transactions

• Not just for concurrency: mutations are automatically cleaned up on transaction rollback

http://nbronson.github.com/scala-stm/Friday, May 25, 12

Page 34: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Software Transactional Memory

Friday, May 25, 12

Page 35: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Software Transactional Memory

import scala.concurrent.stm._

Friday, May 25, 12

Page 36: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Software Transactional Memory

import scala.concurrent.stm._

// Global reference to current memory imageval memoryImage = Ref(MemoryImage(initial state))

Friday, May 25, 12

Page 37: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Software Transactional Memory

import scala.concurrent.stm._

// Global reference to current memory imageval memoryImage = Ref(MemoryImage(initial state))

// Example read & updateatomic { implicit txn => memoryImage() = memoryImage().copy( filters = updated filters)}

Friday, May 25, 12

Page 38: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Software Transactional Memory

import scala.concurrent.stm._

// Global reference to current memory imageval memoryImage = Ref(MemoryImage(initial state))

// Example read & updateatomic { implicit txn => memoryImage() = memoryImage().copy( filters = updated filters)}

Parentheses to read the current value

Friday, May 25, 12

Page 39: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Software Transactional Memory

import scala.concurrent.stm._

// Global reference to current memory imageval memoryImage = Ref(MemoryImage(initial state))

// Example read & updateatomic { implicit txn => memoryImage() = memoryImage().copy( filters = updated filters)}

Parentheses to read the current valueParentheses and

assignment to update

Friday, May 25, 12

Page 40: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Software Transactional Memory

import scala.concurrent.stm._

// Global reference to current memory imageval memoryImage = Ref(MemoryImage(initial state))

// Example read & updateatomic { implicit txn => memoryImage() = memoryImage().copy( filters = updated filters)}

Parentheses to read the current valueParentheses and

assignment to update

Represents current transaction

Friday, May 25, 12

Page 41: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

STM Pitfalls

• Atomic block may be retried, so only mutate data managed by STM. Bad:var start = falseatomic { implicit txn => memoryImage().trustAnchors. find { ta => ta.locator == trustAnchorLocator }. filter { ta => ta.enabled && ta.status.isIdle }. foreach { ta => memoryImage() = memoryImage(). startProcessingTrustAnchor(ta.locator) start = true }}if (start) runValidation()

Friday, May 25, 12

Page 42: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

STM Pitfalls

• Atomic block may be retried, so only mutate data managed by STM. Good:

val start = atomic { implicit txn => memoryImage().trustAnchors. find { ta => ta.locator == trustAnchorLocator }. filter { ta => ta.enabled && ta.status.isIdle }. map { ta => memoryImage() = memoryImage(). startProcessingTrustAnchor(ta.locator) }.isDefined}

if (start) runValidation()

Friday, May 25, 12

Page 43: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Agents

Friday, May 25, 12

Page 44: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Agents of T

• Always share current state, reading is “free”

• Queue of pending updates, executed in the background, sequentially

Agent[T]

Reads never block

Updates T => T are queued

Executed sequentiallyin the background

Friday, May 25, 12

Page 45: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Agent Example

private val _validatedAnnouncements = Agent(Vector.empty[ValidatedAnnouncement])

Friday, May 25, 12

Page 46: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Agent Example

private val _validatedAnnouncements = Agent(Vector.empty[ValidatedAnnouncement])

def validatedAnnouncements = _validatedAnnouncements()

Friday, May 25, 12

Page 47: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Agent Example

private val _validatedAnnouncements = Agent(Vector.empty[ValidatedAnnouncement])

def validatedAnnouncements = _validatedAnnouncements()

def revalidate(announcements: Seq[BgpAnnouncement], roas : Seq[Roa]) { _validatedAnnouncements.sendOff { _ => validate(announcements, roas) }}

Friday, May 25, 12

Page 48: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Agents integrate with STM

• Allows you to update some state and send a computation to an Agent when a STM transaction commits

• Comparable to using a transactional database and message queue, but in-memory

Friday, May 25, 12

Page 49: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Agent Example

private val memoryImage = Ref(MemoryImage(initial state))private val bgpAnnouncements = Ref(Vector.empty[BgpAnnouncement])private val validatedAnnouncements = Agent(Vector.empty[ValidatedAnnouncement])

// Update and start announcement validationatomic { implicit txn => memoryImage() = memoryImage().copy(filters = Vector.empty) val roas = memoryImage().validatedObjects.roas val announcements = bgpAnnouncements() _validatedAnnouncements.sendOff { _ => validate(announcements, roas) }}

Friday, May 25, 12

Page 50: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Futures

Friday, May 25, 12

Page 51: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Future of T

• Represents a value of type T that may not be available yet

• Expensive computation, network access, asynchronous I/O, etc.

Friday, May 25, 12

Page 52: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Future of T

• Represents a value of type T that may not be available yet

• Expensive computation, network access, asynchronous I/O, etc.

• Can be composed, unlike background threads:

Friday, May 25, 12

Page 53: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Future of T

• Represents a value of type T that may not be available yet

• Expensive computation, network access, asynchronous I/O, etc.

• Can be composed, unlike background threads:

def traverse[A, B](items: List[A]) (f: A => Future[B]) (implicit executor: ExecutionContext): Future[List[B]]

Friday, May 25, 12

Page 54: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Future of T

• Represents a value of type T that may not be available yet

• Expensive computation, network access, asynchronous I/O, etc.

• Can be composed, unlike background threads:

def traverse[A, B](items: List[A]) (f: A => Future[B]) (implicit executor: ExecutionContext): Future[List[B]]

E.g. list of URLs to retrieve

Friday, May 25, 12

Page 55: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Future of T

• Represents a value of type T that may not be available yet

• Expensive computation, network access, asynchronous I/O, etc.

• Can be composed, unlike background threads:

def traverse[A, B](items: List[A]) (f: A => Future[B]) (implicit executor: ExecutionContext): Future[List[B]]

E.g. list of URLs to retrieve

E.g. fetch URL

Friday, May 25, 12

Page 56: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Future of T

• Represents a value of type T that may not be available yet

• Expensive computation, network access, asynchronous I/O, etc.

• Can be composed, unlike background threads:

def traverse[A, B](items: List[A]) (f: A => Future[B]) (implicit executor: ExecutionContext): Future[List[B]]

E.g. list of URLs to retrieve

E.g. fetch URL How much concurrency?

Friday, May 25, 12

Page 57: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Future of T

• Represents a value of type T that may not be available yet

• Expensive computation, network access, asynchronous I/O, etc.

• Can be composed, unlike background threads:

def traverse[A, B](items: List[A]) (f: A => Future[B]) (implicit executor: ExecutionContext): Future[List[B]]

E.g. list of URLs to retrieve

E.g. fetch URL How much concurrency?

Completed when all completeFriday, May 25, 12

Page 58: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Concurrent Download

val bgpRisDumpUrls = List( "http://www.ris.ripe.net/dumps/riswhoisdump.IPv4.gz", "http://www.ris.ripe.net/dumps/riswhoisdump.IPv6.gz")def downloadBgpRisDump(url: String): Future[BgpRisDump] = ...

Future.traverse(bgpRisDumpsUrls) { url => downloadBgpRisDump(url)}.foreach { bgpRisDump => // All files have been downloaded, potentially in parallel.}

Friday, May 25, 12

Page 59: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Parallelism

Friday, May 25, 12

Page 60: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Concurrency: program with multiple, independent threads of control. Non-deterministic, since the outcome may depend on the particular interleaving at runtime.

Friday, May 25, 12

Page 61: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Concurrency: program with multiple, independent threads of control. Non-deterministic, since the outcome may depend on the particular interleaving at runtime.

Parallelism: runs on multiple processors, hopefully making it run faster. No other affect on program outcome.

Friday, May 25, 12

Page 62: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Parallel collectionsProblem: validate ~435,000 BGP announcements against ~2,000 route origin authorizations

val result = announcements.map { announcement => val matching = roas.findMatching(announcement.prefix) val (validates, invalidates) = matching.partition { roa => roa.isValid(announcement) }

ValidatedAnnouncement( announcement, validates, invalidates)}

Friday, May 25, 12

Page 63: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Parallel collectionsProblem: validate ~435,000 BGP announcements against ~2,000 route origin authorizations

val result = announcements.par.map { announcement => val matching = roas.findMatching(announcement.prefix) val (validates, invalidates) = matching.partition { roa => roa.isValid(announcement) }

ValidatedAnnouncement( announcement, validates, invalidates)}.seq

Friday, May 25, 12

Page 64: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Parallel collections

• Sequential: ~1.4 seconds,Parallel: ~0.8 seconds (75% faster)

• Can be a quick win for CPU-bound tasks

• Deterministic in absence of side-effects, only the performance changes (same, better, worse)

• Often preferable to implementing a smarter algorithm

• We also use this in UI table filtering

Friday, May 25, 12

Page 65: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Actors

Friday, May 25, 12

Page 66: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Actors

• Aren’t Akka and Scala all about actors?

• Planning to try actors to replace Validator-to-Router communication implementation

• Currently uses Netty ChannelHandlers

• Low-level, hard to test, hard to get right

• Replace with Akka I/O manager and one actor per router?

Friday, May 25, 12

Page 67: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Conclusion

Friday, May 25, 12

Page 68: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

• Immutability is golden and so are side-effect free functions

• Concurrency is (still) hard

• But parallelism much easier, almost free

• No single solution to the concurrency problem, use the right tool for the problem at hand

• Scala (like Clojure and Haskell) provides lots of tools that mostly integrate well

Conclusion

Friday, May 25, 12

Page 69: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

... and not covered

• Basic Java concurrency (synchronized, notify, wait), java.util.concurrent

• The LMAX Disruptor and the single writer principle

• Dataflow concurrency

• Reactive programming

• Events, event bus, event loops

• Etc.

Friday, May 25, 12

Page 70: Concurrency In Practice - GOTO Conference · • Initially access was controlled using a single AtomicReference containing the most recent instance ... Concurrency: program with multiple,

Questions?erik rozendaal

Friday, May 25, 12