Typesafe stack - Scala, Akka and Play
-
Upload
luka-zakrajsek -
Category
Technology
-
view
2.438 -
download
7
Transcript of Typesafe stack - Scala, Akka and Play
Typesafe stack
Scala, Akka and Play
Luka Zakrajšek@bancek
December 2012
The Typesafe Stack
• development platform
• easy to build scalable software applications
• seamless integration with existing Java infrastructure
The Typesafe Stack
• Java Virtual Machine
• Scala core
• Akka middleware
• Play web framework
• Tools
• Horizontal scalability
Scala
• general purpose programming language
• object-oriented and functional
• statically typed
• full interoperability with Java
• Twitter, Foursquare, Amazon, LinkedIn
• active community
Object-Oriented
• familiar design patterns from Java
• traits
• mixin-based composition
Functional
• based on the functional principles of Haskell and ML
• avoid shared state
Statically Typed
• expressive type system
• detects and avoids many kinds of application errors at compile time
• no boilerplate code
Extensible
• easy to add new language constructs
• domain-specific languages (DSLs)
Interoperable with Java
• Java bytecode
• existing Java libraries
• extremely mature Java Virtual Machine
• no difference in deployment
• familiar tools
• shorter, faster, more correct code
Type inference
val a = 5val b = 4.5val c = "foo"val error = a * c
def actOn[T](x: T) = x.toString
actOn(a)actOn(c)
Type aliases, closures, first class functions and
comprehensionstype UnaryOp[T, R] = T => R
def run[R](gen: UnaryOp[Int, R]) { for (x <- 1 to 5) println(gen(x))}
run(x => -x)run(x => Array.fill(x)("*").mkString)
Imperative with functional-style
constructs
val someNumbers = List(1, 9, 2, 7, 3, 5)
def onlyOdds = someNumbers.filter(_ % 2 == 1)def onlyEvens = someNumbers.filter(_ % 2 == 0)def sum = someNumbers.sumdef sumAlt = someNumbers.fold(0)(_ + _)
Traits: static mixins
trait Logging { protected def log(fmt: String, args: Any*) { println(fmt.format(args:_*)) }}
class SampleClass extends Logging { log("Init") val a = 1 val b = "foo" log("%d and %s", a, b)}
Pattern matching
def act: Either[Any, Exception] //...
act match { case Left(message: String) => println(message) case Left(count: Int) => counter += count case Left(fallback: Any) => println("Error") case Right(e) => e.printStackTrace()}
Akka
• event-driven middleware framework
• high performance and reliable distributed applications
• decouples business logic from low-level mechanisms
• easily configurable
Simpler Concurrency
• Threads and nonblocking IO are complex and error-prone
• Actor concurrency model
Transactions
• software transactional memory (STM)
• atomically modify the state of many objects at once
• revert all your changes if the transaction fails
Event-driven
• platform for asynchronous event-driven architectures
• non-blocking IO frameworks
Scalability
• multicore servers and multiple nodes
• several million Actors on single machine
Fault-tolerance
• supervisor hierarchies
• Let It Crash
Transparent Remoting
• Remote Actors
• distributed programming model
• unified programming model
Scala & Java APIs
• smooth interoperability
• Spring and Guice integrations
• deploy in your existing Java application server or run stand-alone
Actors
• every actor has a message queue
• actors accepts and choose what to do with messages
• lightweight and asynchronous
Actors
• actors tend to remain bound to single thread
• actors rarely block, thread can remain active for a long duration
• Akka actors occupy 650 bytes
class GreetingActor extends Actor { private var counter = 0 def receive = { case message => { counter += 1 // 1) Hello, Juliet log.info(counter + ") Hello, " + message) } }}
val greetingActor = actorOf[GreetingActor].start
greetingActor ! "Juliet"
Play Framework
• painless web development for Java and Scala
• developer productivity
• RESTful architectures
• clean alternative to bloated Enterprise Java stacks
Live reload
• fix the bug and hit reload
• no need to restart the server
Stateless MVC architecture
• shared-nothing architecture
• use Ajax or offline storage to solve the state problems client-side
• easier to render portions of the page in parallel
Type-safe templating engine
• Scala-based template engine
• syntax and type errors detected by compiler
• routing system is also fully type-checked
Full-stack application framework
• relational database support and object-relational mapping
• integrated cache support
• straightforward RESTful web services
• flexible deployment options
Controller
package controllers
import play.api.mvc._
object Application extends Controller {
def index = Action { Ok("It works!") } }
Router
# Extract the page parameter from the path, or fix the value for /GET / controllers.Application.show(page = "home")GET /:page controllers.Application.show(page)
Scala IDE for Eclipse
• syntax highlighting, code completion, inferred type hovers...
• mixed Scala/Java projects
• incremental compilation
• 3rd party support for IntelliJ and NetBeans
Simple Build Tool (sbt)
• compile code
• run tests
• package jars
• manages dependencies
When not to use it
• developers familiar with Python or Ruby
• already have big codebase
Troubles
• compiler is sometimes very slow
• Scala developers are hard to find
• Buggy tools
• Play Framework 2 is still young
Why do we use it?
• Python as first choice
• a lot of long-lived connections
• good support for WebSockets
• when it compiles, it’s fast
Why do we use it?
• most components in Scala and Play
• also Python and Node.js
• Thrift for communication between components
• Akka for client connections and blocking operations
Why do we use it?
• RESTful API on server
• JavaScript (Angular.JS) on frontend
• router generates helpers for JavaScript
Questions?