SlideShare a Scribd company logo
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
布道中的反思
幸运的是
● 一个有力的支持者
● 一块荒芜的新领域
艰难险阻
● 组织架构
● 团队基因
Lego: A brick system build 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 Monads
John 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 Future
emptysquare
 
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 introduction
vito jeng
 
Python Yield
Python YieldPython Yield
Python Yield
yangjuven
 
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
Romain Lecomte
 
Game unleashedjavascript
Game unleashedjavascriptGame unleashedjavascript
Game unleashedjavascript
Reece 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 Compilers
Functional Thursday
 
JavaScript 2016 for C# Developers
JavaScript 2016 for C# DevelopersJavaScript 2016 for C# Developers
JavaScript 2016 for C# Developers
Rick Beerendonk
 
Using Reflections and Automatic Code Generation
Using Reflections and Automatic Code GenerationUsing Reflections and Automatic Code Generation
Using Reflections and Automatic Code Generation
Ivan Dolgushin
 
Idiomatic Kotlin
Idiomatic KotlinIdiomatic Kotlin
Idiomatic Kotlin
intelliyole
 
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 Opportunity
mvtbiz
 
Automated Video Marketing Systems
Automated Video Marketing SystemsAutomated Video Marketing Systems
Automated Video Marketing Systems
Sister 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 Lego: A brick system build 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 ease
KAI 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 Go
tdc-globalcode
 
SDC - Einführung in Scala
SDC - Einführung in ScalaSDC - Einführung in Scala
SDC - Einführung in Scala
Christian Baranowski
 
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
Sages
 
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 Patterns
ElifTech
 
EcmaScript unchained
EcmaScript unchainedEcmaScript unchained
EcmaScript unchained
Eduard 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 Story
Databricks
 
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
Databricks
 
Job Queue in Golang
Job Queue in GolangJob Queue in Golang
Job Queue in Golang
Bo-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 scala
Ruslan Shevchenko
 
Akka http 2
Akka http 2Akka http 2
Akka http 2
Jean Detoeuf
 
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 APIs
Matt Stubbs
 
Scala - brief intro
Scala - brief introScala - brief intro
Scala - brief intro
Razvan Cojocaru
 
Monadologie
MonadologieMonadologie
Monadologie
league
 

Similar to Lego: A brick system build 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

项目求生指南
项目求生指南项目求生指南
项目求生指南
lunfu zhong
 
Spring boot
Spring bootSpring boot
Spring boot
lunfu zhong
 
Zhongl scala summary
Zhongl scala summaryZhongl scala summary
Zhongl scala summarylunfu zhong
 
Instroduce Hazelcast
Instroduce HazelcastInstroduce Hazelcast
Instroduce Hazelcastlunfu zhong
 
Jvm分享20101228
Jvm分享20101228Jvm分享20101228
Jvm分享20101228
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

Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, BetterWebinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
XfilesPro
 
How to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good PracticesHow to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good Practices
Globus
 
Enhancing Research Orchestration Capabilities at ORNL.pdf
Enhancing Research Orchestration Capabilities at ORNL.pdfEnhancing Research Orchestration Capabilities at ORNL.pdf
Enhancing Research Orchestration Capabilities at ORNL.pdf
Globus
 
Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
Max Andersen
 
BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024
Ortus Solutions, Corp
 
A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
Philip Schwarz
 
Enhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdf
Enhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdfEnhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdf
Enhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdf
Jay Das
 
How Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptxHow Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptx
wottaspaceseo
 
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Globus
 
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Globus
 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
rickgrimesss22
 
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Anthony Dahanne
 
May Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdfMay Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdf
Adele Miller
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
Paco van Beckhoven
 
Large Language Models and the End of Programming
Large Language Models and the End of ProgrammingLarge Language Models and the End of Programming
Large Language Models and the End of Programming
Matt Welsh
 
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdfDominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
AMB-Review
 
RISE with SAP and Journey to the Intelligent Enterprise
RISE with SAP and Journey to the Intelligent EnterpriseRISE with SAP and Journey to the Intelligent Enterprise
RISE with SAP and Journey to the Intelligent Enterprise
Srikant77
 
Lecture 1 Introduction to games development
Lecture 1 Introduction to games developmentLecture 1 Introduction to games development
Lecture 1 Introduction to games development
abdulrafaychaudhry
 
Into the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdfInto the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdf
Ortus Solutions, Corp
 

Recently uploaded (20)

Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, BetterWebinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
 
How to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good PracticesHow to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good Practices
 
Enhancing Research Orchestration Capabilities at ORNL.pdf
Enhancing Research Orchestration Capabilities at ORNL.pdfEnhancing Research Orchestration Capabilities at ORNL.pdf
Enhancing Research Orchestration Capabilities at ORNL.pdf
 
Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
 
BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024
 
A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
 
Enhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdf
Enhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdfEnhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdf
Enhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdf
 
How Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptxHow Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptx
 
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
 
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
 
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
 
May Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdfMay Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdf
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume Montevideo
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
 
Large Language Models and the End of Programming
Large Language Models and the End of ProgrammingLarge Language Models and the End of Programming
Large Language Models and the End of Programming
 
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdfDominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
 
RISE with SAP and Journey to the Intelligent Enterprise
RISE with SAP and Journey to the Intelligent EnterpriseRISE with SAP and Journey to the Intelligent Enterprise
RISE with SAP and Journey to the Intelligent Enterprise
 
Lecture 1 Introduction to games development
Lecture 1 Introduction to games developmentLecture 1 Introduction to games development
Lecture 1 Introduction to games development
 
Into the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdfInto the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdf
 

Lego: A brick system build 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