SlideShare a Scribd company logo
1 of 54
Download to read offline
LEGOlet’s build everything by scala
聚石 @ alibaba-inc.com
关于我
● Scala 爱好者, CSUG 成员, HouseMD的作者
● 来往后端基础服务
● 淘宝中间件
● github.com/zhongl
大纲
● LEGO 由来和理念
● Scala 在应用中的探索
● Scala 在布道中的反思
+ =
LEGO 的由来和理念
扎堆来往 http://laiwang.com
从有线到无线, HTTP 无法满足移动 IM 的场景
Nginx 没得用怎么办?
PC => Nginx / Apache => Jetty / Tomcat
Mobile => ? => Jetty / Tomcat
自有协议, 自研服务
● 参考 SIP 协议, http://tools.ietf.org/html/rfc3261
● JDK7 + Netty 4 = LWS 1.0
Nginx Config
http {
index index.html;
server {
listen 80 defalut_server;
server_name _;
access_log logs/default.access.log main;
server_name_in_redirect off;
root /var/www/default/htdocs;
}
}
LWS Proxy Config https://github.com/typesafehub/config
proxy {
uri = "tls://0.0.0.0:443"
route {
pre {
/reg = ["tcp://10.0.0.1:5902"]
/http = ["tcp://10.0.0.1:5903"]
/rpc = ["tcp://10.0.0.1:5904"]
}
}
http.white.list = ["/http/[^/]/internal/.*"]
}
Config is a DSL
Spray DSL
import spray.routing.SimpleRoutingApp
object Main extends App with SimpleRoutingApp {
implicit val system = ActorSystem("my-system")
startServer(interface = "localhost", port = 8080) {
path("hello") {
get {
complete {
<h1>Say hello to spray</h1>
}
}
}
}
}
为什么不让配置成为代码的
一部分呢?
仅仅是 DSL 还说不上 LEGO
Handler is brick
protected void initChannel(Channel ch)
throws Exception {
final ChannelPipeline pl = ch.pipeline();
pl.addLast(new MessageDecoder());
pl.addLast(new MessageEncoder());
pl.addLast(new LogAccessHandler());
pl.addLast(new ExchangeHandler());
}
所以, Lego 是这样的...
一个最简单的 Ping-Pong 服务器
import lego.dsl._
new Server {
def name = "ping-pong"
tcp.bind(port = 12306) {
Codec() <=> Handle {
case Request(_, hs, _) => Response(200, hs)
}
}
}
在应用中的探索
Domain-Specific Language
Eval https://github.com/twitter/util
import com.xxx.MyConfig
new MyConfig {
val myValue = 1
val myTime = 2.seconds
val myStorage = 14.kilobytes
}
import com.xxx.MyConfig
val config = Eval[MyConfig](new File("config/Development.scala"))
Operators
tcp.bind(port = 5905) {
Codec() <=> Handler {
case Request(_, hs, _) => Response(200, hs)
}
}
trait Stage {
def <=>(right: Stage): Stage = ...
}
Operators
tcp.bind(port = 5905) {
Codec() <=> Route {
case Request(_, h, _) if h ?: ROUTE => direct_to(h :#: ROUTE)
}
}
abstrace class Name(prefix: String) {
def ?:(headers: List[String]) = ...
def :#:(headers: List[String]) = ...
}
val ROUTE = new Name("route:") {}
Question: Why not wrapped class ?
tcp.bind(port = 5905) {
Codec() <=> Route {
case Request(_, h, _) if h ?: ROUTE => direct_to(h :#: ROUTE)
}
}
implicit class Headers(lines: List[String]) {
def ?(prefix: String) = ...
def :#(prefix: String) = ...
}
val ROUTE = "route:"
Operators
"append remote query to received request" in {
pipeline("10.0.0.1:12345" ~ "10.0.0.2:5902") >>> {
"""
|LWP /xxx
|via:tcp://10.0.0.1:12306
|
|
"""
} ==> {
"""
|LWP /xxx
|via:tcp://10.0.0.1:12306?r=10.0.0.1:12345
|
|
"""
}
}
implicit class Pair(a: String) {
def ~(b: String) = (a, b)
}
implicit class PipelineD(s: Stage) {
def >>>(read: Frame) = {...}
def ==>(expect: Frame) = {...}
}
String Interpolator
tcp.bind(port = 5905) {
codec <=> Route {
case Request(r"/http/.+", _, _) => bbl_lwp_http
}
}
def insert_from: List[String] => List[String] =
headers => headers :?: TOKEN map {
case v @ r"""[^_]+_(.+)$uid""" => FROM -> s"$uid $v" :: headers
} getOrElse headers
implicit class RegexContext(val sc: StringContext) extends AnyVal {
def r = new Regex(sc.parts.mkString, sc.parts.tail.map(_ => "x"): _*)
}
WARNING !!!
scala> "123.cm" matches ".+.cm"
res1: Boolean = true
scala> "123.cm" matches ".+.cm"
<console>:1: error: invalid escape character
"123.cm" matches ".+.cm"
scala> "123.cm" match { case s @ r".+.cm" => s; case s => "Ooops" }
res2: String = Ooops
scala> "123.cm" match { case s @ r".+.cm" => s; case s => "Ooops" }
res3: String = 123.cm
Companion object
def filter_header = FilterHeader {
case <<<(Request(u, hs, _)) => (insert_host(u) andThen insert_from)(hs)
case >>>(Response(_, hs, _)) if hs ?: UID => hs :-: UID
}
class FilterHeader(g: PartialFunction[Direction, List[String]]) extends Stage {...}
object FilterHeader {
sealed trait Direction
case class >>>(frame: Frame) extends Direction
case class <<<(frame: Frame) extends Direction
def apply(g: PartialFunction[Direction, List[String]]) = new FilterHeader(g)
}
Funcational Style
Either & For-Comprehension
def uid(hs: List[String]) = {
(hs :?: UID) match {
case Some(uid) => uid
case None =>
(hs :?: TO) match {
case Some(o) => o.split(' ')(0)
case None =>
(hs :?: TOKEN) match {
case Some(t) => t.split('_')(1)
case None => "-"
}
}
}
}
implicit
def e[T]: Option[T] => Either[Unit, T] =
_.toRight(())
def awk(c: Char)(i: Int) =
(_: String).split(c)(i)
def uid(hs: List[String]) = (for {
_ <- (hs :?: UID).left
_ <- (hs :?: TO map awk(' ')(0)).left
_ <- (hs :?: TOKEN map awk('_')(1)).left
_ <- Right("-").left
} yield {}).right.get
Code Reuse
Trait or Object ?
trait T {
def put(a: Any) {
println(a)
}
}
class A extends T {
def hi() {
put("hi")
}
}
object O {
def put(a: Any) {
println(a)
}
}
class B {
import O._
def hi() {
put("hi")
}
}
Trait or Object ?
trait A {
case class B(i: Int)
}
class C extends A {
def !(a:Any) = a match {
case B(0) => println("B(0)")
case b: B => println("B")
case x => println(s"Oops, $x")
}
}
class D extends A {
new C ! B(0)
}
new D // Oops, B(0)
object A {
case class B(i: Int)
}
class C {
import A._
def !(a:Any) = a match {
case B(0) => println("B(0)")
case b: B => println("B")
case x => println(s"Oops, $x")
}
}
import A._
new C ! B(0) // B(0)
Trait, no Object !
trait T {
def size: Int
def isEmpty = size == 0
}
class A extends T {
def size = 5
}
new A().isEmpty // false
Trait & Object !
package scala.collection.convert
trait WrapAsScala {
import Wrappers._
implicit def asScalaIterator[A](it: ju.Iterator[A]): Iterator[A] = ...
implicit def enumerationAsScalaIterator[A](i: ju.Enumeration[A]): Iterator[A] = ...
}
object JavaConversions extends WrapAsScala with ...
Alias
Type
type Frame = (StartLine, Headers, Option[Payload])
type StartLine = String
type Headers = List[String]
type Payload = (Array[Byte], Zip)
type Zip = Boolean
case class Frame(startLine: String, headers: List[String], content: Option[Payload])
case class Payload(data: Array[Byte], zip: Boolean)
WARNING !!!
scala> type Headers = List[String]
defined type alias Headers
scala> :pas
List(1, 2, 3) match {
case _: Headers => println("wrong!")
case _ => println("right!")
}
<console>:10: warning: fruitless type test: a value of type List[Int] cannot also
be a List[String] (the underlying of Headers) (but still might match its erasure)
case _: Headers => println("wrong!")
^
wrong!
Val
scala> val Headers = List
Headers: scala.collection.immutable.List.type = scala.collection.immutable.
List$@7be117eb
scala> val headers = Headers("mid:1")
headers: List[String] = List(mid:1)
scala> val Headers(a) = List("mid:1")
a: String = mid:1
Val & Type
package object transport {
type Event = pipeline.Event
type Command = pipeline.Command
type Write = pipeline.Write
val Write = pipeline.Write
type Read = pipeline.Read
val Read = pipeline.Read
type Stage = pipeline.Stage[Context]
}
Actor Traps
Default Supervisor Strategy
import akka.actor._
class Handler(var i: Int) extends Actor {
def receive = {
case "incr" => i += 1
case "show" => println(i)
case "boom" => throw new Exception
}
}
object Handler {
def props(i: Int) = {
Props(classOf[Handler], i)
}
}
val system = ActorSystem("fun")
val h = system.actorOf(Handler.props(1))
h ! "show" // 1
h ! "incr"
h ! "show" // 2
h ! "boom" // Exception
h ! "show" // 1
WARNING !!!
class Connector(remote: Address) extends Actor {
import context.system
IO(Tcp) ! Tcp.Connect(remote) // be careful
def receive = {
case Tcp.Connected(_, locale) =>
// handling
case Tcp.CommandFailed(_: Tcp.Connect) =>
context stop self
}
}
WARNING !!!
class Connector(remote: Address) extends Actor {
import context.system
IO(Tcp) ! Tcp.Connect(remote)
def receive = {...}
// not work
override def supervisorStrategy = SupervisorStrategy.stoppingStrategy
}
Solution
class ConnectingSupervisor extends Actor { // solution 1
def receive = {
case remote: Address =>
val c = context.actorOf(Connector.props(remote))
...
}
override def supervisorStrategy = SupervisorStrategy.stoppingStrategy
}
class Connector(remote: Address) extends Actor { // solution 2
override def preRestart(reason: Throwable, message: Option[Any]) = {
context stop self
}
}
No Sender
class Pong extends Actor {
def receive = {
case "ping" => sender() ! "pong"
}
}
class Ping(pong: ActorRef) extends Actor {
pong ! "ping"
def receive = ...
}
class Ping(pong: ActorRef) {
pong ! "ping"
}
def !(message: Any)(implicit sender: ActorRef = Actor.noSender): Unit
TCP DEBUG
// application.conf
io {
loggers = ["akka.event.slf4j.Slf4jLogger"]
loglevel = "DEBUG"
tcp {
trace-logging = on
}
}
SBT
github.com/sbt/sbt-native-packager
src/universal
├── bin
│ ├── start
│ └── stop
└── conf
├── logback.xml
└── proxy.scala
target/universal
└── stage
├── bin
├── conf
├── lib
└── logs
> universal:package
packageBin packageOsxDmg packageXzTarball packageZipTarball
Mirror Respository - Artifactory
[repositories]
local
sbt: http://mirror:8081/artifactory/sbt/,[organization]/[module]/
(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/
[artifact](-[classifier]).[ext]
sbt-plugins: http://mirror:8081/artifactory/sbt-plugins/,[organization]/
[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/
[artifact](-[classifier]).[ext]
scala: http://mirror:8081/artifactory/repo/
> sbt -Dsbt.repository.config=.repos clean test
curl get.jenv.io | bash
@linux_china
布道中的反思
幸运的是
● 一个有力的支持者
● 一块荒芜的新领域
艰难险阻
● 组织架构
● 团队基因
LEGOlet’s build everything by scala

More Related Content

What's hot

[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵
[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵
[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵Wanbok Choi
 
Post-Free: Life After Free Monads
Post-Free: Life After Free MonadsPost-Free: Life After Free Monads
Post-Free: Life After Free MonadsJohn De Goes
 
Scala-Gopher: CSP-style programming techniques with idiomatic Scala.
Scala-Gopher: CSP-style programming techniques with idiomatic Scala.Scala-Gopher: CSP-style programming techniques with idiomatic Scala.
Scala-Gopher: CSP-style programming techniques with idiomatic Scala.Ruslan Shevchenko
 
Nikita Popov "What’s new in PHP 8.0?"
Nikita Popov "What’s new in PHP 8.0?"Nikita Popov "What’s new in PHP 8.0?"
Nikita Popov "What’s new in PHP 8.0?"Fwdays
 
SE 20016 - programming languages landscape.
SE 20016 - programming languages landscape.SE 20016 - programming languages landscape.
SE 20016 - programming languages landscape.Ruslan Shevchenko
 
Python Coroutines, Present and Future
Python Coroutines, Present and FuturePython Coroutines, Present and Future
Python Coroutines, Present and Futureemptysquare
 
Java/Scala Lab: Руслан Шевченко - Implementation of CSP (Communication Sequen...
Java/Scala Lab: Руслан Шевченко - Implementation of CSP (Communication Sequen...Java/Scala Lab: Руслан Шевченко - Implementation of CSP (Communication Sequen...
Java/Scala Lab: Руслан Шевченко - Implementation of CSP (Communication Sequen...GeeksLab Odessa
 
Scala introduction
Scala introductionScala introduction
Scala introductionvito jeng
 
Python Yield
Python YieldPython Yield
Python Yieldyangjuven
 
Un dsl pour ma base de données
Un dsl pour ma base de donnéesUn dsl pour ma base de données
Un dsl pour ma base de donnéesRomain Lecomte
 
Game unleashedjavascript
Game unleashedjavascriptGame unleashedjavascript
Game unleashedjavascriptReece Carlson
 
[FT-11][suhorng] “Poor Man's” Undergraduate Compilers
[FT-11][suhorng] “Poor Man's” Undergraduate Compilers[FT-11][suhorng] “Poor Man's” Undergraduate Compilers
[FT-11][suhorng] “Poor Man's” Undergraduate CompilersFunctional Thursday
 
JavaScript 2016 for C# Developers
JavaScript 2016 for C# DevelopersJavaScript 2016 for C# Developers
JavaScript 2016 for C# DevelopersRick Beerendonk
 
Using Reflections and Automatic Code Generation
Using Reflections and Automatic Code GenerationUsing Reflections and Automatic Code Generation
Using Reflections and Automatic Code GenerationIvan Dolgushin
 
Idiomatic Kotlin
Idiomatic KotlinIdiomatic Kotlin
Idiomatic Kotlinintelliyole
 
Go Concurrency Basics
Go Concurrency Basics Go Concurrency Basics
Go Concurrency Basics ElifTech
 

What's hot (20)

[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵
[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵
[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵
 
Post-Free: Life After Free Monads
Post-Free: Life After Free MonadsPost-Free: Life After Free Monads
Post-Free: Life After Free Monads
 
Scala-Gopher: CSP-style programming techniques with idiomatic Scala.
Scala-Gopher: CSP-style programming techniques with idiomatic Scala.Scala-Gopher: CSP-style programming techniques with idiomatic Scala.
Scala-Gopher: CSP-style programming techniques with idiomatic Scala.
 
Nikita Popov "What’s new in PHP 8.0?"
Nikita Popov "What’s new in PHP 8.0?"Nikita Popov "What’s new in PHP 8.0?"
Nikita Popov "What’s new in PHP 8.0?"
 
SE 20016 - programming languages landscape.
SE 20016 - programming languages landscape.SE 20016 - programming languages landscape.
SE 20016 - programming languages landscape.
 
Python Coroutines, Present and Future
Python Coroutines, Present and FuturePython Coroutines, Present and Future
Python Coroutines, Present and Future
 
Java Script Workshop
Java Script WorkshopJava Script Workshop
Java Script Workshop
 
F[5]
F[5]F[5]
F[5]
 
Java/Scala Lab: Руслан Шевченко - Implementation of CSP (Communication Sequen...
Java/Scala Lab: Руслан Шевченко - Implementation of CSP (Communication Sequen...Java/Scala Lab: Руслан Шевченко - Implementation of CSP (Communication Sequen...
Java/Scala Lab: Руслан Шевченко - Implementation of CSP (Communication Sequen...
 
Scala introduction
Scala introductionScala introduction
Scala introduction
 
Python Yield
Python YieldPython Yield
Python Yield
 
Un dsl pour ma base de données
Un dsl pour ma base de donnéesUn dsl pour ma base de données
Un dsl pour ma base de données
 
Game unleashedjavascript
Game unleashedjavascriptGame unleashedjavascript
Game unleashedjavascript
 
[FT-11][suhorng] “Poor Man's” Undergraduate Compilers
[FT-11][suhorng] “Poor Man's” Undergraduate Compilers[FT-11][suhorng] “Poor Man's” Undergraduate Compilers
[FT-11][suhorng] “Poor Man's” Undergraduate Compilers
 
F[1]
F[1]F[1]
F[1]
 
F sh3tdkeq
F sh3tdkeqF sh3tdkeq
F sh3tdkeq
 
JavaScript 2016 for C# Developers
JavaScript 2016 for C# DevelopersJavaScript 2016 for C# Developers
JavaScript 2016 for C# Developers
 
Using Reflections and Automatic Code Generation
Using Reflections and Automatic Code GenerationUsing Reflections and Automatic Code Generation
Using Reflections and Automatic Code Generation
 
Idiomatic Kotlin
Idiomatic KotlinIdiomatic Kotlin
Idiomatic Kotlin
 
Go Concurrency Basics
Go Concurrency Basics Go Concurrency Basics
Go Concurrency Basics
 

Viewers also liked

Real world scala
Real world scalaReal world scala
Real world scalalunfu zhong
 
Unique Opportunity
Unique OpportunityUnique Opportunity
Unique Opportunitymvtbiz
 
Automated Video Marketing Systems
Automated Video Marketing SystemsAutomated Video Marketing Systems
Automated Video Marketing SystemsSister Technologies
 
Engadget Chinese iPhone App 2010 (Sky Chen)
Engadget Chinese iPhone App 2010 (Sky Chen)Engadget Chinese iPhone App 2010 (Sky Chen)
Engadget Chinese iPhone App 2010 (Sky Chen)Sky Chen
 
Automated Video Marketing System & Video SEO - Automotive & Real Estate Solut...
Automated Video Marketing System & Video SEO - Automotive & Real Estate Solut...Automated Video Marketing System & Video SEO - Automotive & Real Estate Solut...
Automated Video Marketing System & Video SEO - Automotive & Real Estate Solut...Sister Technologies
 

Viewers also liked (7)

Real world scala
Real world scalaReal world scala
Real world scala
 
Unique Opportunity
Unique OpportunityUnique Opportunity
Unique Opportunity
 
Automated Video Marketing Systems
Automated Video Marketing SystemsAutomated Video Marketing Systems
Automated Video Marketing Systems
 
Statistics
StatisticsStatistics
Statistics
 
Engadget Chinese iPhone App 2010 (Sky Chen)
Engadget Chinese iPhone App 2010 (Sky Chen)Engadget Chinese iPhone App 2010 (Sky Chen)
Engadget Chinese iPhone App 2010 (Sky Chen)
 
Automated Video Marketing System & Video SEO - Automotive & Real Estate Solut...
Automated Video Marketing System & Video SEO - Automotive & Real Estate Solut...Automated Video Marketing System & Video SEO - Automotive & Real Estate Solut...
Automated Video Marketing System & Video SEO - Automotive & Real Estate Solut...
 
Resume Updated
Resume UpdatedResume Updated
Resume Updated
 

Similar to LEGOlet’s build everything by scala

Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with ClojureDmitry Buzdin
 
GDG Devfest 2019 - Build go kit microservices at kubernetes with ease
GDG Devfest 2019 - Build go kit microservices at kubernetes with easeGDG Devfest 2019 - Build go kit microservices at kubernetes with ease
GDG Devfest 2019 - Build go kit microservices at kubernetes with easeKAI CHU CHUNG
 
TDC2018SP | Trilha Go - Processando analise genetica em background com Go
TDC2018SP | Trilha Go - Processando analise genetica em background com GoTDC2018SP | Trilha Go - Processando analise genetica em background com Go
TDC2018SP | Trilha Go - Processando analise genetica em background com Gotdc-globalcode
 
Wprowadzenie do technologii Big Data / Intro to Big Data Ecosystem
Wprowadzenie do technologii Big Data / Intro to Big Data EcosystemWprowadzenie do technologii Big Data / Intro to Big Data Ecosystem
Wprowadzenie do technologii Big Data / Intro to Big Data EcosystemSages
 
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...GeeksLab Odessa
 
Go Concurrency Patterns
Go Concurrency PatternsGo Concurrency Patterns
Go Concurrency PatternsElifTech
 
EcmaScript unchained
EcmaScript unchainedEcmaScript unchained
EcmaScript unchainedEduard Tomàs
 
User Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love StoryUser Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love StoryDatabricks
 
User Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love StoryUser Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love StoryDatabricks
 
Job Queue in Golang
Job Queue in GolangJob Queue in Golang
Job Queue in GolangBo-Yi Wu
 
Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Iterative Spark Developmen...
Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Iterative Spark Developmen...Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Iterative Spark Developmen...
Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Iterative Spark Developmen...Data Con LA
 
scala-gopher: async implementation of CSP for scala
scala-gopher:  async implementation of CSP  for  scalascala-gopher:  async implementation of CSP  for  scala
scala-gopher: async implementation of CSP for scalaRuslan Shevchenko
 
Stream or not to Stream?

Stream or not to Stream?
Stream or not to Stream?

Stream or not to Stream?
Lukasz Byczynski
 
(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?Tomasz Wrobel
 
Big Data LDN 2017: Processing Fast Data With Apache Spark: the Tale of Two APIs
Big Data LDN 2017: Processing Fast Data With Apache Spark: the Tale of Two APIsBig Data LDN 2017: Processing Fast Data With Apache Spark: the Tale of Two APIs
Big Data LDN 2017: Processing Fast Data With Apache Spark: the Tale of Two APIsMatt Stubbs
 
Monadologie
MonadologieMonadologie
Monadologieleague
 

Similar to LEGOlet’s build everything by scala (20)

Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 
GDG Devfest 2019 - Build go kit microservices at kubernetes with ease
GDG Devfest 2019 - Build go kit microservices at kubernetes with easeGDG Devfest 2019 - Build go kit microservices at kubernetes with ease
GDG Devfest 2019 - Build go kit microservices at kubernetes with ease
 
TDC2018SP | Trilha Go - Processando analise genetica em background com Go
TDC2018SP | Trilha Go - Processando analise genetica em background com GoTDC2018SP | Trilha Go - Processando analise genetica em background com Go
TDC2018SP | Trilha Go - Processando analise genetica em background com Go
 
SDC - Einführung in Scala
SDC - Einführung in ScalaSDC - Einführung in Scala
SDC - Einführung in Scala
 
Wprowadzenie do technologii Big Data / Intro to Big Data Ecosystem
Wprowadzenie do technologii Big Data / Intro to Big Data EcosystemWprowadzenie do technologii Big Data / Intro to Big Data Ecosystem
Wprowadzenie do technologii Big Data / Intro to Big Data Ecosystem
 
Scala 2 + 2 > 4
Scala 2 + 2 > 4Scala 2 + 2 > 4
Scala 2 + 2 > 4
 
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
 
Go Concurrency Patterns
Go Concurrency PatternsGo Concurrency Patterns
Go Concurrency Patterns
 
EcmaScript unchained
EcmaScript unchainedEcmaScript unchained
EcmaScript unchained
 
User Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love StoryUser Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love Story
 
User Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love StoryUser Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love Story
 
Job Queue in Golang
Job Queue in GolangJob Queue in Golang
Job Queue in Golang
 
Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Iterative Spark Developmen...
Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Iterative Spark Developmen...Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Iterative Spark Developmen...
Big Data Day LA 2016/ Hadoop/ Spark/ Kafka track - Iterative Spark Developmen...
 
scala-gopher: async implementation of CSP for scala
scala-gopher:  async implementation of CSP  for  scalascala-gopher:  async implementation of CSP  for  scala
scala-gopher: async implementation of CSP for scala
 
Akka http 2
Akka http 2Akka http 2
Akka http 2
 
Stream or not to Stream?

Stream or not to Stream?
Stream or not to Stream?

Stream or not to Stream?

 
(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?
 
Big Data LDN 2017: Processing Fast Data With Apache Spark: the Tale of Two APIs
Big Data LDN 2017: Processing Fast Data With Apache Spark: the Tale of Two APIsBig Data LDN 2017: Processing Fast Data With Apache Spark: the Tale of Two APIs
Big Data LDN 2017: Processing Fast Data With Apache Spark: the Tale of Two APIs
 
Scala - brief intro
Scala - brief introScala - brief intro
Scala - brief intro
 
Monadologie
MonadologieMonadologie
Monadologie
 

More from lunfu zhong

More from lunfu zhong (6)

项目求生指南
项目求生指南项目求生指南
项目求生指南
 
Spring boot
Spring bootSpring boot
Spring boot
 
Zhongl scala summary
Zhongl scala summaryZhongl scala summary
Zhongl scala summary
 
Housemd
HousemdHousemd
Housemd
 
Instroduce Hazelcast
Instroduce HazelcastInstroduce Hazelcast
Instroduce Hazelcast
 
Jvm分享20101228
Jvm分享20101228Jvm分享20101228
Jvm分享20101228
 

Recently uploaded

Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceCALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceanilsa9823
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comFatema Valibhai
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...Health
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerThousandEyes
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsAndolasoft Inc
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️anilsa9823
 

Recently uploaded (20)

Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceCALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 

LEGOlet’s build everything by scala

  • 1. LEGOlet’s build everything by scala 聚石 @ alibaba-inc.com
  • 2. 关于我 ● Scala 爱好者, CSUG 成员, HouseMD的作者 ● 来往后端基础服务 ● 淘宝中间件 ● github.com/zhongl
  • 3. 大纲 ● LEGO 由来和理念 ● Scala 在应用中的探索 ● Scala 在布道中的反思
  • 7. Nginx 没得用怎么办? PC => Nginx / Apache => Jetty / Tomcat Mobile => ? => Jetty / Tomcat
  • 8. 自有协议, 自研服务 ● 参考 SIP 协议, http://tools.ietf.org/html/rfc3261 ● JDK7 + Netty 4 = LWS 1.0
  • 9. Nginx Config http { index index.html; server { listen 80 defalut_server; server_name _; access_log logs/default.access.log main; server_name_in_redirect off; root /var/www/default/htdocs; } }
  • 10. LWS Proxy Config https://github.com/typesafehub/config proxy { uri = "tls://0.0.0.0:443" route { pre { /reg = ["tcp://10.0.0.1:5902"] /http = ["tcp://10.0.0.1:5903"] /rpc = ["tcp://10.0.0.1:5904"] } } http.white.list = ["/http/[^/]/internal/.*"] }
  • 11. Config is a DSL
  • 12. Spray DSL import spray.routing.SimpleRoutingApp object Main extends App with SimpleRoutingApp { implicit val system = ActorSystem("my-system") startServer(interface = "localhost", port = 8080) { path("hello") { get { complete { <h1>Say hello to spray</h1> } } } } }
  • 15. Handler is brick protected void initChannel(Channel ch) throws Exception { final ChannelPipeline pl = ch.pipeline(); pl.addLast(new MessageDecoder()); pl.addLast(new MessageEncoder()); pl.addLast(new LogAccessHandler()); pl.addLast(new ExchangeHandler()); }
  • 17. 一个最简单的 Ping-Pong 服务器 import lego.dsl._ new Server { def name = "ping-pong" tcp.bind(port = 12306) { Codec() <=> Handle { case Request(_, hs, _) => Response(200, hs) } } }
  • 20. Eval https://github.com/twitter/util import com.xxx.MyConfig new MyConfig { val myValue = 1 val myTime = 2.seconds val myStorage = 14.kilobytes } import com.xxx.MyConfig val config = Eval[MyConfig](new File("config/Development.scala"))
  • 21. Operators tcp.bind(port = 5905) { Codec() <=> Handler { case Request(_, hs, _) => Response(200, hs) } } trait Stage { def <=>(right: Stage): Stage = ... }
  • 22. Operators tcp.bind(port = 5905) { Codec() <=> Route { case Request(_, h, _) if h ?: ROUTE => direct_to(h :#: ROUTE) } } abstrace class Name(prefix: String) { def ?:(headers: List[String]) = ... def :#:(headers: List[String]) = ... } val ROUTE = new Name("route:") {}
  • 23. Question: Why not wrapped class ? tcp.bind(port = 5905) { Codec() <=> Route { case Request(_, h, _) if h ?: ROUTE => direct_to(h :#: ROUTE) } } implicit class Headers(lines: List[String]) { def ?(prefix: String) = ... def :#(prefix: String) = ... } val ROUTE = "route:"
  • 24. Operators "append remote query to received request" in { pipeline("10.0.0.1:12345" ~ "10.0.0.2:5902") >>> { """ |LWP /xxx |via:tcp://10.0.0.1:12306 | | """ } ==> { """ |LWP /xxx |via:tcp://10.0.0.1:12306?r=10.0.0.1:12345 | | """ } } implicit class Pair(a: String) { def ~(b: String) = (a, b) } implicit class PipelineD(s: Stage) { def >>>(read: Frame) = {...} def ==>(expect: Frame) = {...} }
  • 25. String Interpolator tcp.bind(port = 5905) { codec <=> Route { case Request(r"/http/.+", _, _) => bbl_lwp_http } } def insert_from: List[String] => List[String] = headers => headers :?: TOKEN map { case v @ r"""[^_]+_(.+)$uid""" => FROM -> s"$uid $v" :: headers } getOrElse headers implicit class RegexContext(val sc: StringContext) extends AnyVal { def r = new Regex(sc.parts.mkString, sc.parts.tail.map(_ => "x"): _*) }
  • 26. WARNING !!! scala> "123.cm" matches ".+.cm" res1: Boolean = true scala> "123.cm" matches ".+.cm" <console>:1: error: invalid escape character "123.cm" matches ".+.cm" scala> "123.cm" match { case s @ r".+.cm" => s; case s => "Ooops" } res2: String = Ooops scala> "123.cm" match { case s @ r".+.cm" => s; case s => "Ooops" } res3: String = 123.cm
  • 27. Companion object def filter_header = FilterHeader { case <<<(Request(u, hs, _)) => (insert_host(u) andThen insert_from)(hs) case >>>(Response(_, hs, _)) if hs ?: UID => hs :-: UID } class FilterHeader(g: PartialFunction[Direction, List[String]]) extends Stage {...} object FilterHeader { sealed trait Direction case class >>>(frame: Frame) extends Direction case class <<<(frame: Frame) extends Direction def apply(g: PartialFunction[Direction, List[String]]) = new FilterHeader(g) }
  • 29. Either & For-Comprehension def uid(hs: List[String]) = { (hs :?: UID) match { case Some(uid) => uid case None => (hs :?: TO) match { case Some(o) => o.split(' ')(0) case None => (hs :?: TOKEN) match { case Some(t) => t.split('_')(1) case None => "-" } } } } implicit def e[T]: Option[T] => Either[Unit, T] = _.toRight(()) def awk(c: Char)(i: Int) = (_: String).split(c)(i) def uid(hs: List[String]) = (for { _ <- (hs :?: UID).left _ <- (hs :?: TO map awk(' ')(0)).left _ <- (hs :?: TOKEN map awk('_')(1)).left _ <- Right("-").left } yield {}).right.get
  • 31. Trait or Object ? trait T { def put(a: Any) { println(a) } } class A extends T { def hi() { put("hi") } } object O { def put(a: Any) { println(a) } } class B { import O._ def hi() { put("hi") } }
  • 32. Trait or Object ? trait A { case class B(i: Int) } class C extends A { def !(a:Any) = a match { case B(0) => println("B(0)") case b: B => println("B") case x => println(s"Oops, $x") } } class D extends A { new C ! B(0) } new D // Oops, B(0) object A { case class B(i: Int) } class C { import A._ def !(a:Any) = a match { case B(0) => println("B(0)") case b: B => println("B") case x => println(s"Oops, $x") } } import A._ new C ! B(0) // B(0)
  • 33. Trait, no Object ! trait T { def size: Int def isEmpty = size == 0 } class A extends T { def size = 5 } new A().isEmpty // false
  • 34. Trait & Object ! package scala.collection.convert trait WrapAsScala { import Wrappers._ implicit def asScalaIterator[A](it: ju.Iterator[A]): Iterator[A] = ... implicit def enumerationAsScalaIterator[A](i: ju.Enumeration[A]): Iterator[A] = ... } object JavaConversions extends WrapAsScala with ...
  • 35. Alias
  • 36. Type type Frame = (StartLine, Headers, Option[Payload]) type StartLine = String type Headers = List[String] type Payload = (Array[Byte], Zip) type Zip = Boolean case class Frame(startLine: String, headers: List[String], content: Option[Payload]) case class Payload(data: Array[Byte], zip: Boolean)
  • 37. WARNING !!! scala> type Headers = List[String] defined type alias Headers scala> :pas List(1, 2, 3) match { case _: Headers => println("wrong!") case _ => println("right!") } <console>:10: warning: fruitless type test: a value of type List[Int] cannot also be a List[String] (the underlying of Headers) (but still might match its erasure) case _: Headers => println("wrong!") ^ wrong!
  • 38. Val scala> val Headers = List Headers: scala.collection.immutable.List.type = scala.collection.immutable. List$@7be117eb scala> val headers = Headers("mid:1") headers: List[String] = List(mid:1) scala> val Headers(a) = List("mid:1") a: String = mid:1
  • 39. Val & Type package object transport { type Event = pipeline.Event type Command = pipeline.Command type Write = pipeline.Write val Write = pipeline.Write type Read = pipeline.Read val Read = pipeline.Read type Stage = pipeline.Stage[Context] }
  • 41. Default Supervisor Strategy import akka.actor._ class Handler(var i: Int) extends Actor { def receive = { case "incr" => i += 1 case "show" => println(i) case "boom" => throw new Exception } } object Handler { def props(i: Int) = { Props(classOf[Handler], i) } } val system = ActorSystem("fun") val h = system.actorOf(Handler.props(1)) h ! "show" // 1 h ! "incr" h ! "show" // 2 h ! "boom" // Exception h ! "show" // 1
  • 42. WARNING !!! class Connector(remote: Address) extends Actor { import context.system IO(Tcp) ! Tcp.Connect(remote) // be careful def receive = { case Tcp.Connected(_, locale) => // handling case Tcp.CommandFailed(_: Tcp.Connect) => context stop self } }
  • 43. WARNING !!! class Connector(remote: Address) extends Actor { import context.system IO(Tcp) ! Tcp.Connect(remote) def receive = {...} // not work override def supervisorStrategy = SupervisorStrategy.stoppingStrategy }
  • 44. Solution class ConnectingSupervisor extends Actor { // solution 1 def receive = { case remote: Address => val c = context.actorOf(Connector.props(remote)) ... } override def supervisorStrategy = SupervisorStrategy.stoppingStrategy } class Connector(remote: Address) extends Actor { // solution 2 override def preRestart(reason: Throwable, message: Option[Any]) = { context stop self } }
  • 45. No Sender class Pong extends Actor { def receive = { case "ping" => sender() ! "pong" } } class Ping(pong: ActorRef) extends Actor { pong ! "ping" def receive = ... } class Ping(pong: ActorRef) { pong ! "ping" } def !(message: Any)(implicit sender: ActorRef = Actor.noSender): Unit
  • 46. TCP DEBUG // application.conf io { loggers = ["akka.event.slf4j.Slf4jLogger"] loglevel = "DEBUG" tcp { trace-logging = on } }
  • 47. SBT
  • 48. github.com/sbt/sbt-native-packager src/universal ├── bin │ ├── start │ └── stop └── conf ├── logback.xml └── proxy.scala target/universal └── stage ├── bin ├── conf ├── lib └── logs > universal:package packageBin packageOsxDmg packageXzTarball packageZipTarball
  • 49. Mirror Respository - Artifactory [repositories] local sbt: http://mirror:8081/artifactory/sbt/,[organization]/[module]/ (scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/ [artifact](-[classifier]).[ext] sbt-plugins: http://mirror:8081/artifactory/sbt-plugins/,[organization]/ [module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/ [artifact](-[classifier]).[ext] scala: http://mirror:8081/artifactory/repo/ > sbt -Dsbt.repository.config=.repos clean test
  • 50. curl get.jenv.io | bash @linux_china