Scala, Akka, and Play: An Introduction on Heroku

51
Scala, Akka, and Play: an Introduction on Heroku Havoc Pennington Typesafe

Transcript of Scala, Akka, and Play: An Introduction on Heroku

Page 1: Scala, Akka, and Play: An Introduction on Heroku

Scala, Akka, and Play: an Introduction on Heroku

Havoc Pennington

Typesafe

Page 2: Scala, Akka, and Play: An Introduction on Heroku

Overview

Modernizing development on the Java Virtual Machine

– Scala: practical, superior alternative to Java with incremental migration path

– Akka: proven Actor model gives horizontal scale for both Java and Scala, without the pain points of explicit threads

– Play: popular Rails-style convention-over-configuration lightweight web framework for both Java and Scala

– All supported on Heroku, a cloud platform with the same developer-friendly point of view

2

Developer-friendly, horizontally scalable,with a pragmatic path to adoption

Page 3: Scala, Akka, and Play: An Introduction on Heroku

Scala

Page 4: Scala, Akka, and Play: An Introduction on Heroku

4

Where it comes from

Scala has established itself as one of the main alternative languages on the JVM.

Created by Martin Odersky, who also designed generics in Java 5 and implemented the javac compiler. He works with a team at EPFL (École polytechnique fédérale de Lausanne) in addition to the team at Typesafe.

Prehistory:

1996 – 1997: Pizza1998 – 2000: GJ, Java generics, javac

( “make Java better” )

Timeline: 2003 – 2006: The Scala “Experiment”2006 – 2009: An industrial strength programming language

( “make a better Java” )

Page 5: Scala, Akka, and Play: An Introduction on Heroku

Quick Scala Facts

• Vibrant open source community• Wide commercial adoption• Catching fire last couple years, but has been maturing many years• Supports both object-oriented and functional styles• Great interoperability with Java• Static type safety• Type inference makes it concise like a dynamic language• “Scala” implies a “scalable language”

– Horizontal scale across cores– Developer scale: manage complex projects

Page 6: Scala, Akka, and Play: An Introduction on Heroku

6

Page 7: Scala, Akka, and Play: An Introduction on Heroku

7

Scala drives its social graph service: 380-400 M

transactions/day

Migrated core messaging service from Ruby to sustain 3 orders of magnitude growth

Select Commercial Users

EU’s largest energy firm migrated a 300K lines contract modeling platform from Java to

Scala

Entire web site and all services written in Scala

Approved for general production use

Page 8: Scala, Akka, and Play: An Introduction on Heroku

8

Community TractionOpen source ecosystem with• Tens of thousands of downloads, scala-

lang.org visitors• 20 books• 40+ active user groups

Page 9: Scala, Akka, and Play: An Introduction on Heroku

9

GitHub and StackOverflow

From http://www.dataists.com/2010/12/ranking-the-popularity-of-programming-langauges/

Page 10: Scala, Akka, and Play: An Introduction on Heroku

Practical Migration and Interoperability

10

• Scala differs from Java only on the source code level

• Once you have a .jar or .war, it just looks like Java

• Scala code can seamlessly import and use any Java class

• Projects can have a mix of Java and Scala files

• Deploy Scala to any cloud or container that supports Java

import java.net.URL;

Import java.io.InputStream;

URL u = new URL(“http://foo.com”);

InputStream s = u.openStream();

s.close();

Java:

Scala: import java.net.URL

val u = new URL(“http://foo.com”)val s = u.openStream()s.close()

Page 11: Scala, Akka, and Play: An Introduction on Heroku

Less Code

When going from Java to Scala, expect at least a factor of 2 reduction in LOC.

But does it matter? Doesn’t Eclipse write these extra lines for me?

This does matter. Eye-tracking experiments* show that for program comprehension, average time spent per word of source code is constant.

So, roughly, half the code means half the time necessary to understand it.

*G. Dubochet. Computer Code as a Medium for Human Communication: Are Programming Languages Improving?In 21st Annual Psychology of Programming Interest Group Conference, pages 174-187, Limerick, Ireland, 2009.

Guy Steele: “Switching from Java to Scala reduced size of Fortress typechecker by a factor of 4”.

11

Page 12: Scala, Akka, and Play: An Introduction on Heroku

12

A class ...public class Person {

public final String name;

public final int age;

Person(String name, int age) {

this.name = name;

this.age = age;

}

}

class Person(val name: String, val age: Int)

... in Java:

... in Scala:

Page 13: Scala, Akka, and Play: An Introduction on Heroku

13

... and its usageimport java.util.ArrayList;

...

Person[] people;

Person[] minors;

Person[] adults;

{ ArrayList<Person> minorsList = new ArrayList<Person>();

ArrayList<Person> adultsList = new ArrayList<Person>();

for (int i = 0; i < people.length; i++)

(people[i].age < 18 ? minorsList : adultsList)

.add(people[i]);

minors = minorsList.toArray(people);

adults = adultsList.toArray(people);

}

... in Java:

... in Scala: val people: Array[Person]val (minors, adults) = people partition (_.age < 18)

Page 14: Scala, Akka, and Play: An Introduction on Heroku

14

Both Object-Oriented and Functional

• Scala is not “religious” on programming paradigm: it tries to let you do what's practical for the situation

• In some cases, Scala is “more object oriented” than Java; for example– primitive types are full-fledged objects– static methods are replaced by methods on singleton objects

Page 15: Scala, Akka, and Play: An Introduction on Heroku

15

Detour: What is Functional Programming?

• Emphasizes transformation (take a value, return a new value) over mutable state (take a value, change the value in-place)

• Think ƒ(x)• Also includes some cultural traditions, such as transforming lists

with map and reduce• Advantages include:

– Inherently parallelizable and thread-safe– Enables many optimizations, such as lazy evaluation– Can make code more flexible and generic, for example by supporting

composition

Page 16: Scala, Akka, and Play: An Introduction on Heroku

16

Imperative Style (Java)

public static void addOneToAll(ArrayList<Integer> items) { for (int i = 0; i < items.size(); ++i) { items.set(i, items.get(i) + 1); } }

Mutates (modifies) the list in-place

Page 17: Scala, Akka, and Play: An Introduction on Heroku

17

Functional Style (Java)

public static List<Integer> addOneToAll(List<Integer> items) { ArrayList<Integer> result = new ArrayList<Integer>(); for (int i : items) { result.add(i + 1); } return result; }

Returns a new list, leaving original untouched

Page 18: Scala, Akka, and Play: An Introduction on Heroku

18

Functional Enables Composition

public static List<Integer> addTwoToAll(List<Integer> items) { return addOneToAll(addOneToAll(items)); }

(Composition is great for HTTP request handlers, by the way.)

Page 19: Scala, Akka, and Play: An Introduction on Heroku

19

Imperative Style (Scala)

def addOneToAll(items : mutable.IndexedSeq[Int]) = { var i = 0 while (i < items.length) { items.update(i, items(i) + 1) i += 1 } }

Mutates (modifies) the list in-place

Page 20: Scala, Akka, and Play: An Introduction on Heroku

20

Functional Style (Scala)

def addOneToAll(items : Seq[Int]) = items map { _ + 1 }

Returns a new list, leaving original untouched

Anonymous function applied toeach item in the list

Page 21: Scala, Akka, and Play: An Introduction on Heroku

21

Functional is not...

• A syntax. You can use functional style in both Java and Scala.• A bunch of jargon (Monads, Functors, etc.); the Scala standard

library and the Programming in Scala book for example take care to avoid this sort of academic language.

• A silver bullet.

Page 22: Scala, Akka, and Play: An Introduction on Heroku

22

Best fit for the problem domain

• Something like a simulation or a UI toolkit might map most naturally to object-oriented style

• Something like a file format transformation or HTTP request might map most naturally to functional style

• There is no need to be religious• You can also use Scala as “Java with fewer characters to type,” and

ignore the functional style

Page 23: Scala, Akka, and Play: An Introduction on Heroku

23

End of detour

Next: how Scala uses functional style to support horizontal scale...

Page 24: Scala, Akka, and Play: An Introduction on Heroku

Horizontal Scale

The world of mainstream software is changing:

– Moore’s law now achieved by increasing # of cores not clock cycles

– Huge volume workloads that require horizontalscaling

24

Data from Kunle Olukotun, Lance Hammond, Herb Sutter, Burton Smith, Chris Batten, and Krste

Asanovic

Page 25: Scala, Akka, and Play: An Introduction on Heroku

Concurrency is too hard

Almost every program that uses threads is full of bugs.

25

Page 26: Scala, Akka, and Play: An Introduction on Heroku

The Root of The Problem

• Non-determinism caused by concurrent threads accessing shared mutable state.

• It helps to encapsulate state in actors or transactions, but the fundamental problem stays the same.

• So,

non-determinism = parallel processing + mutable state

• To get deterministic processing, avoid the mutable state!• Avoiding mutable state means programming functionally.

26

var x = 0

async { x = x + 1 }

async { x = x * 2 }

// can give 0, 1, 2

Page 27: Scala, Akka, and Play: An Introduction on Heroku

27

Remember this code from before...import java.util.ArrayList;

...

Person[] people;

Person[] minors;

Person[] adults;

{ ArrayList<Person> minorsList = new ArrayList<Person>();

ArrayList<Person> adultsList = new ArrayList<Person>();

for (int i = 0; i < people.length; i++)

(people[i].age < 18 ? minorsList : adultsList)

.add(people[i]);

minors = minorsList.toArray(people);

adults = adultsList.toArray(people);

}

... in Java:

... in Scala: val people: Array[Person]val (minors, adults) = people partition (_.age < 18)

Page 28: Scala, Akka, and Play: An Introduction on Heroku

28

Let's make it parallel...

?... in Java:

... in Scala: val people: Array[Person]val (minors, adults) = people.par partition (_.age < 18)

Page 29: Scala, Akka, and Play: An Introduction on Heroku

Recommended: Read the Book

• Very clearly-written, by Scala's creator and designer

• Highly recommended to start here

Page 30: Scala, Akka, and Play: An Introduction on Heroku

Scala in Summary

• Beautiful interoperability with Java: mix Scala and Java as desired, no huge rewrites

• Conciseness means dramatic improvement in maintainability and productivity

• Functional style seamlessly supports parallel computation, for example parallel collections have exactly the same API as serial

• Vibrant community, hockey-stick growth curve, and available commercial support

Page 31: Scala, Akka, and Play: An Introduction on Heroku

Akka

Page 32: Scala, Akka, and Play: An Introduction on Heroku

What is Akka?

• An implementation of the “Actor model”– The actor model is an alternative to explicit threads, originally used in

the highly reliable Erlang environment

• An API for both Java and Scala– Many people use Akka but not Scala, even though Akka is written in

Scala.

Page 33: Scala, Akka, and Play: An Introduction on Heroku

What else is Akka?

“Akka is the platform for next generation event-driven, scalable, and fault-tolerant

architectures on the JVM”

A toolkit with many tools, but let's focus on Actors...

Page 34: Scala, Akka, and Play: An Introduction on Heroku

34

An Actor

public class HelloWorldActor extends UntypedActor { public void onReceive(Object msg) { getContext().replySafe(((String) msg) + “ World”); }}

class HelloWorldActor extends Actor { def receive = { case msg : String => self reply (msg + “ World”) }}

... in Java:

... in Scala:

Page 35: Scala, Akka, and Play: An Introduction on Heroku

Actors for Concurrent Programming

• Developer writes an object, called an Actor, which handles messages.

• Each actor instance runs in only one thread at a time, so no synchronization is required for actor state.

• Akka dispatcher schedules actors on threads – or even on multiple machines – as needed. Can have millions of actors, an actor does not “use up” a thread.

• Mutable state is safely single-threaded.• Easier for programmers to create reliable concurrent processing.• Many sources of contention, races, locking and dead-locks are

removed.• No need to use locks or java.util.concurrent – at all. Even though

you're using mutable state, it's encapsulated in actors.

35

Page 36: Scala, Akka, and Play: An Introduction on Heroku

Separation of Concerns

• “Business logic” does not concern itself with the concurrency mechanism or scheduling. Just implement what you'd like to happen in response to each message.

• Note the similarity to Scala collections– In “items foreach { _ + 1 }” rather than a while loop, the Scala

library “drives” the application of “{ _ + 1 }” to “items” and can make that transparently parallel

– In the same way, Akka “drives” the dispatch of messages to actors, allowing it to Do The Right Thing

– Developer says “what” but avoids hardcoding “how”

36

Page 37: Scala, Akka, and Play: An Introduction on Heroku

Other Goodies

• Actor model• Event-driven dispatcher can run millions of actors• Remoting• Supervisors (fault-tolerance)• Software Transactional Memory (STM)• Futures, Pools, and other handy utilities

Akka offers a comprehensive toolkit for clustering, concurrency, and fault-tolerance.

Page 38: Scala, Akka, and Play: An Introduction on Heroku

Akka Core

Page 39: Scala, Akka, and Play: An Introduction on Heroku

Modules

Page 40: Scala, Akka, and Play: An Introduction on Heroku

40

Akka in Summary

• Akka is an implementation of the Actor model for both Java and Scala.

• Actors encapsulate mutable state with the guarantee of one message at a time.

• Actor instances don't need to do any locking or think about threads, eliminating a whole class of bugs and mental overhead.

• The magic comes from the dispatcher, which (by default) combines an event-driven loop with a thread pool for scalability.

• A single JVM can host millions of actors – far more actors than threads.

• Akka comes with a complete toolkit for distributed, fault-tolerant computing, built on actors as a base.

• Highly modular: the core actor jar has ZERO dependencies.

Page 41: Scala, Akka, and Play: An Introduction on Heroku

Play

Page 42: Scala, Akka, and Play: An Introduction on Heroku

Both Scala and Java

• Like Akka, Play has both Java and Scala APIs• Originally a Java framework, but increasing emphasis on Scala• You could use the Java version of Play and just happen to write

some files in Scala, but there are also dedicated Scala-tuned APIs in Play's Scala module

Page 43: Scala, Akka, and Play: An Introduction on Heroku

It's a Framework

• Framework, not a library; many decisions are made in advance, you can often change them but there are defaults

• For example:– Model-View-Controller approach– Selenium is set up for testing– There's a database API built-in with good default mappings to REST

– memcached support built-in– Predefined “prod” and “dev” modes– default template system

• Lets you get started quickly, instead of having to make a dozen decisions first. Can change decisions “as needed.”

• Always start with a complete “hello world” project, and iterate it from there.

Page 44: Scala, Akka, and Play: An Introduction on Heroku

Scripting-style Web Development

• The Play Framework feels like a Python or Ruby framework, rather than a traditional Java framework

• No compile and restart; server compiles and recompiles on the fly, so just edit, reload, edit, reload. Compilation and other errors appear right in the browser.

• Like developing with a “scripting language” … but you have static type safety!

• With Scala, your code can be as concise as it would be in a “scripting language”

Page 45: Scala, Akka, and Play: An Introduction on Heroku

Stateless

• Play is “share-nothing” so no need for communication between nodes

• State can be kept in your SQL or NoSQL store, in memcached, or browser cookies

Page 46: Scala, Akka, and Play: An Introduction on Heroku

Seeing is believing

• play new helloworld --with scala• play run

Page 47: Scala, Akka, and Play: An Introduction on Heroku

Play in Summary

• Both Scala and Java friendly• Emphasis on rapid development and good defaults, rather than

absolute flexibility• Similar in feel to Python and Ruby frameworks, for example shares

the MVC model• Try out the Java or Scala tutorials on the Play website

Page 48: Scala, Akka, and Play: An Introduction on Heroku

Heroku

Page 49: Scala, Akka, and Play: An Introduction on Heroku

Heroku Supports Scala and Play

• With Heroku, the unit of deployment is a git repository: that is, you deploy the source code, not a .war file or similar

• This means Heroku must know how to build from source• With Heroku's “Java support” you could already deploy a Scala

application using Maven• Most Scala developers use Simple Build Tool, however• Play Framework has built-in build facilities so it can build on browser

reload

Heroku now supports Play Framework applications, plus (experimentally) SBT apps might work...

Page 50: Scala, Akka, and Play: An Introduction on Heroku

Demo

Let's run some stuff on Heroku.

Page 51: Scala, Akka, and Play: An Introduction on Heroku

Takeaways

These technologies offer a genuine opportunity for huge productivity gains over traditional Java.

They are practical to adopt incrementally without huge rewrites.

Typesafe offers commercial support and training for Scala and Akka.

On Twitter: @Typesafe

Learn more at typesafe.com51