Develop realtime and distributed web
with Scala and XitrumNgoc Dao
Saigon Xmas 2014Hanoi New Year 2015
http://www.toptal.com/scala/why-should-i-learn-scala
http://cacm.acm.org/magazines/2014/4/173220-unifying-functional-and-object-oriented-programming-with-scala/fulltext
Slides will be shared at:http://www.slideshare.net/ngocdaothanh
This talk is long.Please ask question immediately when you have one.
For questions/discussions after this talk, please post to:https://www.facebook.com/groups/720666194693928
You can also post to scala-user group:https://groups.google.com/d/forum/scala-user
About meWorking at Mobilus in Tokyo: http://mobilus.co.jp/● Server side● Android, iOS
Interests:● Realtime and distributed systems● Web frameworks
(have been written several for Erlang, Scala, Java)● Big data, analytics (learning Apache Spark)
Open source:● https://github.com/ngocdaothanh● https://github.com/xitrum-framework● https://github.com/sinetja● https://github.com/netty
Scala@Japan
● Meetups: ~monthly (in Tokyo)● Conferences: yearly
○ 2013:http://scalamatsuri.org/2013/en/program/index.html
○ 2014:http://scalamatsuri.org/en/program/index.htmlhttp://scalamatsuri.org/en/unconference/index.html
Red Sand DunesPhan Thiet
About you
I guess you already know OOP.
Functional programming:● How many of you have used Ruby?
(somewhat functional, popular)● Have used a more functional language?
(Lisp, Haskell, Erlang, Clojure, F# etc.)
Scala looks like Java and runs on JVM. It’s convenient if you already know Java:● How many of you have used Java?● Have used Scala?
● Why use Scala? Compare with Java, Ruby, Node.js etc.● Books, sites
Getting started:● Install Scala● Ways to run Scala program: Hello World
Scala = OOP + functional:● Learn Scala’s functional feature via collections● Learn Scala’s OOP feature via the Animals exercise
Some tools:● Development:
○ REPL (Read–Eval–Print Loop), SBT (Scala Build Tool)○ IDEs: Eclipse, IntelliJ
● Production: ○ xitrum-package○ Scalive
PART 1/5: Scala overview
● Web app ≈ normal app + routing● Xitrum:
○ Compare with Scalatra, Lift, Play○ Basic usage:
■ Add routes to the previous demos■ respondXxx
○ Swagger UI, Swagger Codegen○ Metrics○ i18n
PART 2/5: Use Scala for web
● Compare with Node.js● Future and future composition● Actor model and Akka actor
↑ NEW programming paradigmA language that doesn't change the way you think about programming is not worth learning.○ Actor vs Thread○ Actor vs Future○ Some pitfalls
● Akka FSM
PART 3/5: Use Scala for concurrency
● Realtime web● WebSocket, Socket.IO, SockJS● Tictactoe web game
PART 4/5: Use Scala for realtime web
PART 5/5: Use Scala for distributed systems
Compare with Redis
Remoting:● Akka remoting
Clustering:● Akka clustering● Glokka● Hazelcast
Scale Tictactoe to multiple servers
● Why use Scala? Compare with Java, Ruby, Node.js etc.● Books, sites
Getting started:● Install Scala● Ways to run Scala program: Hello World
Scala = OOP + functional:● Learn Scala’s functional feature via collections● Learn Scala’s OOP feature via the Animals exercise
Some tools:● Development:
○ REPL (Read–Eval–Print Loop), SBT (Scala Build Tool)○ IDEs: Eclipse, IntelliJ
● Production: ○ xitrum-package○ Scalive
PART 1/5: Scala overview
● Trendy: Used by by Apple, Foursquare, Guardian, LinkedIn, Netflix, Quora, Sony Pictures Entertainment, Twitter, UK Guardian etc.
● Compare with Java, Ruby, Node.js etc.● Language: ≈ Java + Ruby
○ Fast speed of Java + nice syntax of Ruby:Faster than Ruby + syntax nicer than Java
○ Flexible:■ Static + dynamic:
Compiled to Java .class or run as script like Ruby■ OOP of Java + functional of Ruby
http://www.quora.com/Why-is-Swift-so-similar-to-Scala● Not only a good language: Scala has toys
○ Ecosystem: Can reuse all Java libs○ Concurrent/parallel: Future, Akka (≈ Erlang)○ Big data: Apache Spark
Why use Scala?
Books, sites
● http://www.scala-lang.org/documentation/● http://twitter.github.io/effectivescala/● https://github.com/lauris/awesome-scala● https://github.com/akullpp/awesome-java● Search
Learn Scala “enough” to do projects
How much is “enough”?
Level A1:Beginning application programmer
● Java-like statements and expressions: standard operators, method calls, conditionals, loops, try/catch
● class, object, def, val, var, import, package● Infix notation for method calls● Simple closures● Collections with map, filter, etc● for-expressions
http://www.scala-lang.org/old/node/8610
Level A2:Intermediate application programmer
● Pattern matching● Trait composition● Recursion, in particular tail recursion● XML literals
Level A3:Expert application programmer
● Folds, i.e. methods such as foldLeft, foldRight
● Streams and other lazy data structures● Actors● Combinator parsers
Level L1:Junior library designer
● Type parameters● Traits● Lazy vals● Control abstraction, currying● By-name parameters
Level L2:Senior library designer
● Variance annotations● Existential types (e.g., to interface with Java
wildcards)● Self type annotations and the cake pattern
for dependency injection● Structural types (aka static duck typing)● Defining map/flatmap/withFilter for new kinds
of for-expressions● Extractors
Level L3:Expert library designer
● Early initializers● Abstract types● Implicit definitions● Higher-kinded types
A1 → A2/L1 → A3/L2 → L3
Install Scala
1. Download fromhttp://www.scala-lang.org/
2. Config PATH:PATH=path/to/scala-2.11.4/bin:$PATH
REPL (Read–Eval–Print Loop) demo:scala command
Ways to run Scala program
● println("Hello World")● Run as script with scala● Compile with scalac and run with scala● Compile with scalac and run with java
SBT (Scala Build Tool)
http://www.scala-sbt.org/
● Dependency library manager + build tool● Like “gem” + “rake” of Ruby● Like Maven, Gradle● Has plugins to generate project files for IDEs,
like Eclipse and IntelliJ● Has plugins to collect and package .jar files,
ready to deploy to production environment
(Make, Ant are just build tools, not dependency library managers)
Install SBT
1. Download fromhttp://www.scala-sbt.org/download.html
2. Config PATH:PATH=path/to/sbt/bin/dir:$PATH
sbt:java -Xms256M -Xmx512M-jar `dirname $0`/sbt-launch-0.13.7.jar "$@"
Learn SBT:http://www.scala-sbt.org/documentation.html
Simple SBT-based project structure
build.sbtorganization := "com.mycompany"
name := "hello"
version := "1.0"
scalaVersion := "2.11.4"
scalacOptions ++= Seq("-deprecation", "-feature", "-unchecked")
javacOptions ++= Seq("-source", "1.6", "-target", "1.6")
libraryDependencies += "tv.cntt" %% "xitrum" % "3.21"
libraryDependencies += "ch.qos.logback" % "logback-classic" % "1.1.2"
Packaged .jar file:hello_2.11-1.0.jar
$ sbt tasksconsole Starts the Scala interpreter
compile Compiles sourcesclean Deletes files produced by the buildrun Runs a main class
package Produces project jar filepublish Publishes project jar file to a repositorypublish-local Copies project jar file to ~/.ivy2
test Executes all teststest-only Executes the tests provided as argumentstest-quick Executes the tests that either failed before
SBT plugins
http://www.scala-sbt.org/release/docs/Community-Plugins.html
Generate Eclipse project:https://github.com/typesafehub/sbteclipse
Generate IntelliJ project:https://github.com/mpeltonen/sbt-idea
Package project:https://github.com/xitrum-framework/xitrum-package
Hello World demo
● sbt console● sbt run● sbt eclipse● Run in Eclipse● Debug in Eclipse● sbt xitrum-package● Run with java● Add dependency library
http://search.maven.org/● Scalive
Rules of thumb
Use dependency manager:● Do not download dependency libraries
manually● Do not commit dependency libraries
IDEs:● Generate project files for IDEs● Do not commit project files
Scala = OOP + functional
Unifying Object-Oriented and Functional Programminghttp://web.stanford.edu/class/cs94si/OOPFP.pdf
Functional language
● Pass a function as an argument to another function=> Convenient syntaxf(123, g)f(123, { // ...})
● Immutable data structures=> Thread-safe○ Tail recursion
Learn Scala’s functional feature via collections
● From a collection, create another collection of same size=> map
● From a collection, create another collection of larger size=> flatMap
● From a collection, create another collection of smaller size=> filter
● From a collection, create one element=> foldLeft, foldRight, reduce
http://www.scala-lang.org/api/current/index.html#scala.collection.Seq
map
flatMap
filter
foldLeft
Roll
val a = 1
var b = 1b = 2
val → immutable:val c = Seq(1, 2, 3)
var → immutable:var d = Seq(1, 2, 3)d = Seq(4, 5, 6)
val → mutable:val e = Array(1, 2, 3)e(0) = 4
var → mutable:var f = Array(1, 2, 3)f = Array(4, 5, 6)f(0) = 4
val VS varimmutable VS mutable collection
Order of preference (best practice):● val● var● val → immutable: strictly functional● var → immutable● val → mutable● var → mutable: do not use
Some languages only allow val → immutableScala is flexible:var and mutable are OK to use in small, closed scope
For your curiosity: How to write programs with only constants?
Example problem:
Without var, mutable:● Generate a collection of positive numbers
that are <= n, and are multiple of 3 or 5.gen(n: Int): Seq[Int]
● Calculate sum of all numbers in a collection.sum(nums: Seq[Int]): Int
With var and mutable
import scala.collection.mutable.ArrayBufferdef gen(n: Int): Seq[Int] = { val buf = ArrayBuffer[Int]() var i = 1 while (i <= n) { if (i % 3 == 0 || i % 5 == 0) buf.append(i) i += 1 } buf}
def gen(n: Int): Seq[Int] = { val nums = 1 to n nums.filter { i => i % 3 == 0 || i % 5 == 0 }}
def gen(n: Int): Seq[Int] = { for { i <- 1 to n if (i % 3 == 0 || i % 5 == 0) } yield i}
Without var and mutable
● Use recursion to loop● Optimize: Use tail recursion
○ Use accumulator
def gen(n: Int): Seq[Int] = { // Stop condition if (n < 3) return Seq()
// Recursion if (n % 3 == 0 || n % 5 == 0) gen(n - 1) :+ n else gen(n - 1)}
Stackoverflowif n is big enough
def genAcc( n: Int, acc: Seq[Int]): Seq[Int] = { if (n < 3) return acc
// Tail recursion; Scala compiler will // convert to “while” loop if (n % 3 == 0 || n % 5 == 0) genAcc(n - 1, n +: acc) else genAcc(n - 1, acc)}
def gen(n: Int) = genAcc(n, Seq())
def genAcc( n: Int, acc: Seq[Int]): Seq[Int] = { if (n < 3) return acc
if (n % 3 == 0 || n % 5 == 0) genAcc(n - 1, n +: acc) else genAcc(n - 1, acc)}
How to write programs with only constants?
State is storedat function arguments
State is set/changedat function call
How I learn an OOP language:● Learn basic syntax● Learn collections● Animals exercise:
abstraction, encapsulation,inheritance, polymorphism
Learn Scala’s OOP feature via the Animals exercise
Animals exercise
trait (interface) Animal● name: String● talk()
class Cat extends Animalclass Dog extends Animal
class Zoo● addAnimal(a: Animal)● talkAll()
scala-lang.org → /api/ Companion object Class Trait
http://youtu.be/GQxUEAXX_fE
How to read Scaladoc
● Web app ≈ normal app + routing● Xitrum:
○ Compare with Scalatra, Lift, Play○ Basic usage:
■ Add routes to the previous demos■ respondXxx
○ Swagger UI, Swagger Codegen○ i18n
PART 2/5: Use Scala for web
Web ≈ Routing
function
Input Output
function
Input Output
Web ≈ RoutingA web library/framework is not worth using if its routing feature sucks.
function
Request Response
function
ResponseRequest
Request
Request
Router
Xitrum
http://xitrum-framework.github.io/
Compare with Scalatra, Lift, Play
Demos:https://github.com/xitrum-framework/xitrum-demos
Skeleton to create new project:https://github.com/xitrum-framework/xitrum-new
● Basic usage:○ Add routes to the previous demos○ respondXxx
● Swagger UI, Swagger Codegen● Metrics● i18n
Xitrum
● Compare with Node.js● Future and future composition● Actor model and Akka actor
↑ NEW programming paradigmA language that doesn't change the way you think about programming is not worth learning.○ Actor vs Thread○ Actor vs Future○ Some pitfalls
● Akka FSM
PART 3/5: Use Scala for concurrency
Compare with Node.js
Node.js:● Single thread => Single core● Complicate to scale to multiple cores or multiple
servers; except for shared-nothing (non-realtime) systems
● Callback hell
Scala:● Multiple threads; immutable data structures, future, and
actor provide more safety for multithread programming● Easy to scale● No callback hell
Future
http://docs.scala-lang.org/overviews/core/futures.html
Think about Future as a thread pool with some nice methods to:● send tasks to it● get results● handle failures● compose the above together
Future composition
ff
ff
f
f
f
f1
f2
f3
f
Think about Node.js callback hell!
● Future.sequence● for comprehension
val taskParams = Seq(123, 456, 789)val taskFutures: Seq[Future[String]] = tasks.map { ms =>
future { Thread.sleep(ms) s"Result for $ms" }}
val gatheredFuture: Future[Seq[String]] = Future.sequence(taskFutures)
val purchase = for { usd <- future { con.getValue(USD) } chf <- future { con.getValue(CHF) } if isProfitable(usd, chf)} yield connection.buy(amount, chf)
purchase onSuccess { amount =>println("Purchased " + amount + " CHF")
}
↑ NEW programming paradigm
A language that doesn't change the way you think about programming is not worth learning.Alan Perlis(the first recipient of the Turing Award)
Actor model and Akka actor
Benefit of actor in one sentence
C vs Java:You can use memory without having to release memory manually.
Thread vs actor:You can use concurrency without having to create threads manually.
Don't communicate by sharing memory; share memory by communicating.
Actor model● Actor =
states + mailbox + behaviors (msg handlers)
● From outside, can’t manipulate actors directly.● To interact with an actor, must send messages to it.● Each actor has a mailbox, messages are put to mailbox,
and processed one by one. ← An actor is like a single threaded process (each actor is like a Node.js process); it doesn’t do more than one thing at a time.
http://www.cs.tsukuba.ac.jp/~yas/cs/csys-2013/2013-12-03/
Actor vs Thread
Thread:● Heavy weight: Can only create not too many threads;
usually: 2000~5000● Shared state ← Source of bugs● Passive: Have to call object.method() to make the object
alive.Actor:● Light weight: Can create millions of actors;
usually: ~2.5 million actors/GB● Self contained, shared nothing● Active: Actors are alive by themselves. ← Easy to model
programs that have millions of on-going things (very high level of concurrency), like MMOG games.
Actor vs Thread
● Thread: n dimensions, hard to reason about.● Actor: 1D, one thing at a time.
var1
var1
Actor vs Thread
Just like JVM automatically manages memory for you:● Actor is a high level logical way to think, to
model programs.● At lower level, actors run above a thread
pool.
Actor vs Future
Actor:● Messaging● Scheduling● FSM● Monitoring and supervision● Location transparency
(actors on one server can send messages to actors on another server)=> Easier to scale out to multiple servers/clustering
Future:● Syntax is easier to write● Composable● More typesafe
Akka http://akka.io/(an implementation of the actor model)
Summary:https://jraviton.wordpress.com/2015/01/16/lets-brush-up-on-scala-actors/
Demo: Counter
// First, define messagesobject Counter { case class Inc(amount: Int) case class Dec(amount: Int)}
import akka.actor.Actor
// Define actor state and message handlersclass Counter(name: String) extends Actor { // Actor state private var value = 0
...
...
import Counter._
// Message handlers def receive = { case Inc(amount) => value += amount println(s"Value: $value")
case Dec(amount) => value -= amount println(s"Value: $value") }}
import akka.actor.{ActorSystem, Props}
// Think of this as a thread poolval system = ActorSystem("mysystem")
// Create actor reference (actor instance)val c1 = system.actorOf( Props(new Counter("mylock")))
// Send messages to the actorc1 ! Counter.Inc(1)c1 ! Counter.Dec(2)
Some pitfalls
Send mutable msgs between actors.↑ May lead to bug, if actor A sends msg M to actor B, state of B incorporates M, then M is later changed by A.=> Shared memory
Fix: Use immutable messages.
Some pitfallsFrom inside actor:anObject.foo(new Callback { def onCallback() { // Modify actor state directly }})↑ May lead to bug, because the actor’s thread and the callback’s thread may be 2 different threads. Remember: An actor is like a single threaded process, can’t do more than one thing at a time. An actor should be self contained, shared nothing.
Fix: self ! msgFromCallback
Good read
● Concurrent Programming for Scalable Web Architectureshttp://berb.github.io/diploma-thesis/index.html
● Functions + Messages + Concurrency = Erlanghttp://www.infoq.com/presentations/joe-armstrong-erlang-qcon08
● Akka dochttp://doc.akka.io/docs/akka/2.3.8/scala.html
Akka FSM
● FSM: Finite State Machine● Implemented based on actors● Very good for realtime multiplayer games, to
manage states of game sessions and inter-player interactions
Example:Code Lockhttps://github.com/ngocdaothanh/code-lock-fsm-akka
● Realtime web● WebSocket, Socket.IO, SockJS● Tictactoe web game
PART 4/5: Use Scala for realtime web
HTTP problem:Server can send data to clients only one time.
Some years ago:Flash (open TCP socket connection to server)
Now:WebSockethttps://developer.mozilla.org/en-US/docs/WebSockets/Writing_WebSocket_client_applications
Realtime web ≈ server push
var sock = new WebSocket('ws://domain/path');
sock.onopen = function() { console.log('onopen');};
sock.onmessage = function(e) { console.log('onmessage: ' + e.data); sock.send(e.data);};
sock.onclose = function() { console.log('onclose');};
Server can push data to clients multiple times
WebSocket problem
New browsers are required:● Internet Explorer: 10● Firefox: 6● Chrome: 4● Safari: 5● Opera: 12.10
WebSocket emulators
SockJS: WebSocket-like API● JavaScript client:
https://github.com/sockjs/sockjs-client● Protocol:
https://github.com/sockjs/sockjs-protocolhttp://sockjs.github.io/sockjs-protocol/sockjs-protocol-0.3.3.html
● Closer to WebSocket, much simpler than Socket.IO=> Server side support for many languages
Socket.IO: More complicate built-in features, like rooms● http://socket.io/● Node.js
SockJS
● Provides WebSocket-like API● Supports all browsers, e.g. IE 6● Transports: websocket xhr-streaming xdr-
streaming iframe-eventsource iframe-htmlfile xhr-polling xdr-polling iframe-xhr-polling jsonp-polling
● Requires○ Client side: sockjs.js○ Server side: SockJS protocol
implementation
var sock = new WebSocket('ws://domain/path');
sock.onopen = function() {
};
sock.onmessage = function(e) {
sock.send(e.data);
};
sock.onclose = function() {
};
var sock = new SockJS('http://domain/path');
sock.onopen = function() {
};
sock.onmessage = function(e) {
sock.send(e.data);
};
sock.onclose = function() {
};
WebSocket vs SockJS
Tictactoe web game
https://github.com/xitrum-framework/xitrum-tictactoe
Tictactoe web game
Exercises:● Instead of letting player actors send messages directly
to each other, use an intermediate game actor for each game.
● Let users other than the players watch games.● Use Scala.js to convert game logic code written in Scala
to JavaScript, to share game logic code between server side and client side.http://www.scala-js.org/
● Use Akka FSM instead of become.
Compare with Redis
Remoting:● Akka remoting
Clustering:● Akka clustering● Glokka● Hazelcast
Scale Tictactoe to multiple servers
PART 5/5: Use Scala for distributed systems
Compare with Redis
Redis:● Separate process● Single point of failure
Akka, Hazelcast:● In-process
=> Faster, easier to use● Redundancy, failover
Akka remoting
http://doc.akka.io/docs/akka/2.3.8/scala/remoting.html
Akka clustering
http://doc.akka.io/docs/akka/2.3.8/scala/cluster-usage.html
Glokka
https://github.com/xitrum-framework/glokka
A Scala library that allows you to register and lookup actors by names in an Akka cluster.
Hazelcast
Program ≈ Code + Data
Distributed Program ≈ Distributed Code + Distributed Data
Akka ≈ Distributed CodeHazelcast ≈ Distributed Data + Distributed Code
http://hazelcast.org/http://hazelcast.com/
http://docs.hazelcast.org/docs/3.4/manual/html/
● Distributed data structures: Map, Multimap, Queue, Set, List, Topic (pub/sub), Lock, AtomicLong, AtomicReference, Semaphore, CountDownLatch, IdGenerator
● JCache● Distributed ExecutorService● Transaction● MapReduce, Aggregators● Integration: Hibernate, Servlet session replication,
Spring● Client: Java, C++, .NET, REST, memcache
Scale Tictactoe to multiple servers
Only need to change Lobby lookup=> Use Glokka
Config Akka cluster:config/akka.conf
Top Related