3. Who is speaking?
• freelance software consultant based
in Vienna
• Vienna Scala User Group
• web, web, web
4. Who is speaking?
• freelance software consultant based
in Vienna
• Vienna Scala User Group
• web, web, web
• writing a book on reactive web-
applications
http://www.manning.com/
bernhardt
7. But we have many-
core CPUs
• Tilera, Cavium
• Adapteva Parallela
• Xeon PHI
• It's happening!
8. Too many cores?
• "640 kb ought to be enough for
anybody" ~ Bill Gates
9. Too many cores?
• "640 kb ought to be enough for
anybody" ~ Bill Gates
• "4 cores ought to be enough for
anybody" ~ Linus Torvalds1
1
http://highscalability.com/blog/2014/12/31/linus-the-whole-parallel-
computing-is-the-future-is-a-bunch.html
10.
11. Programming with
many cores
• serial approach does not work
• asynchronous programming with
inappropriate tools does not work
drives people insane
• we need (and already have) new
abstractions
• we have to re-evaluate the use of
our old abstractions
12. The problem with mutable state
car.setPosition(0);
car.setPosition(10);
14. The problem with
mutable state
• there is no notion of time, only an
illusion thereof
• changes to a mutable model only
make sense locally if nobody is
watching
• the larger the scope, the harder it
gets to prevent inconsistencies
15. The problem with
locks
• solution workaround for a broken
conceptual model
• hard to reason about
• performance hit
17. Let's make things
even more
complicated:
programming with
many nodes
• scaling out to handle large loads
• scaling out / replication to handle
node failure
18. Let's make things
even more
complicated:
programming with
many nodes
• scaling out to handle large loads
• scaling out / replication to handle
node failure
• problem: networks fail
19. Failure is inevitable
• Jepsen series3
• CAP theorem
• transactions don't really work that
way in distributed systems
3
http://aphyr.com
20. Hard problem to
solve
• Paxos: Consensus solving protocols
• CQRS: Command Query
Responsibility Segregation
• CRDTs: Commutative Replicated
Data Types
26. Declarative
programming
In declarative programming you
describe what you want to get
Example:
val (minors, majors) = users.partition(_.age < 18)
Declarative programming is like
driving with a GPS navigation
system
You can do without, but it's so comfortable
27. Core concepts of FP
• immutability
• functions
• transforming data with functions
28. Immutability
case class Car(brand: String, position: Int)
val car = Car(brand = "DeLorean", position = 0)
val movedCar = car.copy(position = 10)
29. Immutability
case class Car(brand: String, position: Int)
val car = Car(brand = "DeLorean", position = 0)
val movedCar = car.copy(position = 10)
30. Immutability
case class Car(brand: String, position: Int)
val car = Car(brand = "DeLorean", position = 0)
val movedCar = car.copy(position = 10)
33. Functions and higher-order
functions
val isMinor = (age: Int) => age < 18
val (minors, majors) = users.partition(isMinor)
Moving behaviour around instead of moving data
around
34. Transforming data
val addresses = users.filter(_.age > 18)
.map(_.address)
.sortBy(_.city)
Goal: To build increasingly complex behaviour through
a series of transformations / by composing functions
35. Composition
def fetchUser(id: Long): Option[User] = ...
def fetchCar(id: Long): Option[Car] = ...
val carPrice: Option[BigDecimal] = for {
user <- fetchUser(42)
car <- fetchCar(23)
} yield {
user.age + car.price
}
36. Composition
def fetchUser(id: Long): Future[User] = ...
def fetchCar(id: Long): Future[Car] = ...
val carPrice: Future[BigDecimal] = for {
user <- fetchUser(42)
car <- fetchCar(23)
} yield {
user.age + car.price
}
37. Composition
def fetchUser(id: Long): Try[User] = ...
def fetchCar(id: Long): Try[Car] = ...
val carPrice: Try[BigDecimal] = for {
user <- fetchUser(42)
car <- fetchCar(23)
} yield {
user.age + car.price
}
38. Composition
def fetchUser(id: Long): [User] = ...
def fetchCar(id: Long): [Car] = ...
val carPrice: [BigDecimal] = for {
user <- (42)
car <- (23)
} yield {
user.age + car.price
}
39. Maths FTW!
• Option, Future, Try all implement
monadic operations2
• set of data structures following the
same laws
• know one, know them all
• keeping things DRY
• also, it's not that scary
2
https://www.haskell.org/haskellwiki/Monad_tutorials_timeline
47. Play history
• MVC framework, inspired by RoR,
Django, Symfony
• Zenexity
• first version released in 2009
• version 2.0 released in 2012, core
rewritten in Scala
49. Threaded servers
• like a train station with multiple
tracks
• station chief decides which trains go
on which platform
• if there are more trains than
platforms, trains queue up
• if too many trains are queuing up,
huge delays occur and passengers
go home
50. Evented servers
• like a waiter in a restaurant
• runs back and forth between tables
and the kitchen
• does only small tasks that do not
take much time
• one server can each serve many
tables at once
51. Advantages of the evented
approach
• less threads means less memory
• better CPU utilization (reduced context switching)
• (much) higher throughputs than threaded servers
52.
53. History
• first release in January 2010
• based on the Actor model (Erlang)
• message-based asynchronous
concurrency toolkit
• object-oriented programming done
right
54. History
• first release in January 2010
• based on the Actor model (Erlang)
• message-based asynchronous
concurrency toolkit
• object-oriented programming done
right
• Akka is also a mountain in Sweden
59. Sending and receiving messages
case class Script(text: String)
class AudreyHepburn extends Actor {
def receive = {
case Script(text) =>
read(text)
}
}
60. Sending and receiving messages
case class Script(text: String)
class AudreyHepburn extends Actor {
def receive = {
case Script(text) =>
read(text)
}
}
val audrey = ActorSystem.actorOf(Props[Audrey])
audrey ! Script(breakfastAtTiffany)
62. Supervision
class HollyCrazyCatLady extends Actor {
lazy val cats: ActorRef = context
.actorOf[Cat]
.withRouter(
RoundRobinRouter(nrOfInstances = 42)
)
override def supervisorStrategy =
OneForOneStrategy(maxNrOfRetries = 3) {
case t: Throwable =>
log.error("A cat had a problem!",
t)
Restart
}
}
63. Actors out there
• remoting
• clustering
• persistent actors event sourcing
64. CQRS
• high level: separate writes & reads
(performance)
• transform and store everything as
events (write only)
• transform into query model in a
separate store
Immutability (again!)
65. Summary
• many-core is here to stay
• FP is essential to take advantage of
many-core systems
66. Summary
• many-core is here to stay
• FP is essential to take advantage of
many-core systems
• Play and Akka make it possible to
build web-applications that can
scale in and out