SlideShare ist ein Scribd-Unternehmen logo
1 von 54
Downloaden Sie, um offline zu lesen
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

Weitere Àhnliche Inhalte

Was ist angesagt?

[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
 

Was ist angesagt? (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
 

Andere mochten auch

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
 
Resume Updated
Resume UpdatedResume Updated
Resume Updatedguest34635e
 

Andere mochten auch (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
 

Ähnlich wie 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 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
 
SDC - EinfĂŒhrung in Scala
SDC - EinfĂŒhrung in ScalaSDC - EinfĂŒhrung in Scala
SDC - EinfĂŒhrung in ScalaChristian 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 EcosystemSages
 
Scala 2 + 2 > 4
Scala 2 + 2 > 4Scala 2 + 2 > 4
Scala 2 + 2 > 4Emil Vladev
 
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
 
Scala - brief intro
Scala - brief introScala - brief intro
Scala - brief introRazvan Cojocaru
 
Monadologie
MonadologieMonadologie
Monadologieleague
 

Ähnlich wie 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
 

Mehr von lunfu zhong

éĄčç›źæ±‚ç”ŸæŒ‡ć—
éĄčç›źæ±‚ç”ŸæŒ‡ć—éĄčç›źæ±‚ç”ŸæŒ‡ć—
éĄčç›źæ±‚ç”ŸæŒ‡ć—lunfu zhong
 
Spring boot
Spring bootSpring boot
Spring bootlunfu 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戆äș«20101228lunfu zhong
 

Mehr von 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
 

KĂŒrzlich hochgeladen

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
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplatePresentation.STUDIO
 
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
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfproinshot.com
 
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
 
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
 
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
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...kalichargn70th171
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
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
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024Mind IT Systems
 
+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
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionSolGuruz
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
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
 
How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...software pro Development
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfWilly Marroquin (WillyDevNET)
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesVictorSzoltysek
 
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfAzure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfryanfarris8
 

KĂŒrzlich hochgeladen (20)

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
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
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 đŸ”âœ”ïžâœ”ïž
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdf
 
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
 
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
 
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
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
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
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024
 
+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...
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
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
 
How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfAzure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.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