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

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
 
Understanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSageUnderstanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSage
Globus
 
Lecture 1 Introduction to games development
Lecture 1 Introduction to games developmentLecture 1 Introduction to games development
Lecture 1 Introduction to games development
abdulrafaychaudhry
 
Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology SolutionsProsigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns
 
Visitor Management System in India- Vizman.app
Visitor Management System in India- Vizman.appVisitor Management System in India- Vizman.app
Visitor Management System in India- Vizman.app
NaapbooksPrivateLimi
 
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus
 
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
 
Strategies for Successful Data Migration Tools.pptx
Strategies for Successful Data Migration Tools.pptxStrategies for Successful Data Migration Tools.pptx
Strategies for Successful Data Migration Tools.pptx
varshanayak241
 
Explore Modern SharePoint Templates for 2024
Explore Modern SharePoint Templates for 2024Explore Modern SharePoint Templates for 2024
Explore Modern SharePoint Templates for 2024
Sharepoint Designs
 
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoamOpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
takuyayamamoto1800
 
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERRORTROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
Tier1 app
 
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
XfilesPro
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke
 
Accelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with PlatformlessAccelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with Platformless
WSO2
 
GlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote sessionGlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote session
Globus
 
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
Juraj Vysvader
 
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
informapgpstrackings
 
SOCRadar Research Team: Latest Activities of IntelBroker
SOCRadar Research Team: Latest Activities of IntelBrokerSOCRadar Research Team: Latest Activities of IntelBroker
SOCRadar Research Team: Latest Activities of IntelBroker
SOCRadar
 
A Comprehensive Look at Generative AI in Retail App Testing.pdf
A Comprehensive Look at Generative AI in Retail App Testing.pdfA Comprehensive Look at Generative AI in Retail App Testing.pdf
A Comprehensive Look at Generative AI in Retail App Testing.pdf
kalichargn70th171
 
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
 

Recently uploaded (20)

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
 
Understanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSageUnderstanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSage
 
Lecture 1 Introduction to games development
Lecture 1 Introduction to games developmentLecture 1 Introduction to games development
Lecture 1 Introduction to games development
 
Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology SolutionsProsigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology Solutions
 
Visitor Management System in India- Vizman.app
Visitor Management System in India- Vizman.appVisitor Management System in India- Vizman.app
Visitor Management System in India- Vizman.app
 
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024
 
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...
 
Strategies for Successful Data Migration Tools.pptx
Strategies for Successful Data Migration Tools.pptxStrategies for Successful Data Migration Tools.pptx
Strategies for Successful Data Migration Tools.pptx
 
Explore Modern SharePoint Templates for 2024
Explore Modern SharePoint Templates for 2024Explore Modern SharePoint Templates for 2024
Explore Modern SharePoint Templates for 2024
 
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoamOpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
 
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERRORTROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
 
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume Montevideo
 
Accelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with PlatformlessAccelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with Platformless
 
GlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote sessionGlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote session
 
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
 
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
 
SOCRadar Research Team: Latest Activities of IntelBroker
SOCRadar Research Team: Latest Activities of IntelBrokerSOCRadar Research Team: Latest Activities of IntelBroker
SOCRadar Research Team: Latest Activities of IntelBroker
 
A Comprehensive Look at Generative AI in Retail App Testing.pdf
A Comprehensive Look at Generative AI in Retail App Testing.pdfA Comprehensive Look at Generative AI in Retail App Testing.pdf
A Comprehensive Look at Generative AI in Retail App Testing.pdf
 
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
 

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