ááŒáá·áºáá±ááŸá¯á áá áºá ááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááŒáá·áº áá¯ááºáá±á¬ááºááẠá áááºáááºá á¬ážá áá¬áá±á¬ááºážááá·áº ááá¹ááá¬ážáá áºáá¯ááᯠááŒá±á¬ááŒááá¯áá«áááºá ááœá²á·á ááºážááŸá¯á¡á¬áž áá±ážáááºážáá±á¬á¡áá»áá¯ážá¡á á¬ážáá»á¬ážááᯠá¡áá¯á¶ážááŒá¯á á á¯á ááºážáá¬ážáá±á¬áá¬áá¬á áá¬áž (Scala) ááŒáá·áº ááá¯ááºááá¯ááºááá¯ááºá á¬ážááŒá¯áááºá á€ááá¯á·á áºááœáẠááá¯ááá¯á·áá±á¬ááœá²á·á ááºážáá¯á¶áá¯á¶á á¶áá áºáá¯á á¥ááá¬ááᯠáá±ážáá±á¬ááºáá¬ážááŒá®áž á¡áá¯á¶ážá á¯á¶ááœá¶á·ááŒáá¯ážááá¯ážáááºááŸá¯áá¯ááºáááºážá ááºááœáẠá á¯á ááºážáá¬ážáá±á¬ááœá²á·á ááºážáá¯á¶áá áºáá¯ááᯠá¡áá±á¬ááºá¡áááºáá±á¬áºááŒááºážá ááŸá¯áá±á¬áá·áºá¡áá»áá¯ážáá»áá¯ážááᯠááœá±ážááœá±ážáá¬ážáááºá
(
áááá«ááºáž
áá¯á¶ááŒááºá áááºáá»ááá±á¬ ááŒáá·áºáá±ááŸá¯á áá áºáá áºáá¯ááᯠáááºáá±á¬ááºááŒááºážááá¯áááºááŸá¬ node áá»á¬ážá¡á¬ážáá¯á¶ážááẠááŸááºáááºáá±á¬ááœá²á·á ááºážáá¯á¶ááᯠá¡áá¯á¶ážááŒá¯ááŒá®áž á¡ááŒá¬áž node áá»á¬ážááŸáá·áº áááºáá°ááŒá¯áá¬ážááŒááºážááᯠááá¯ááá¯áááºá DevOps áááºážááá¬áá»á¬áž (terraformá ansible ááá¯á·ááá¯áẠááá¯áá²á·ááá¯á·áá±á¬á¡áá¬) ááᯠá¡áá»á¬ážá¡á¬ážááŒáá·áº configuration files (node ââáá áºáá¯á á®á¡ááœáẠáá®ážááŒá¬ážáááºááŸááºáá¬ážáá±á·ááŸááááº) ááᯠá¡ááá¯á¡áá»á±á¬ááºáá¯ááºáá±ážááẠá¡áá¯á¶ážááŒá¯áá«áááºá áááºááœááºáá±ážáááºážááŒá±á¬ááºážáá»á¬ážá¡á¬ážáá¯á¶ážááẠáá°áá®áá±á¬áááá¯ááá¯áá±á¬áá»á¬áž (áá°áá®áá±á¬áá¬ážááŸááºážá¡áá«á¡áááº) ááá¯á¡áá¯á¶ážááŒá¯áá±ááŒá±á¬ááºážáááºáž áá»áœááºá¯ááºááá¯á·áá±áá»á¬á á±ááá¯áá«áááºá ááá¯á·ááá¯ááºáá«áá áá»áœááºá¯ááºááá¯á·áááŒáá·áºáá±ááŸá¯á áá áºááœáẠááá¯ááºáááºáá®ááŸá¯áááŸáááŒááºážááᯠáááºáá±á¬ááºááœá¬ážáá«áááºá JVM ááá¹áá¬ááœááºá á€ááá¯á¡ááºáá»ááºáá¡áá»áá¯ážáááºáá áºáá¯ááŸá¬ áááá¯ááá¯áá±á¬áááºáá±á·áá»áºáá»á¬ážáá«ááŸááá±á¬ á á¬ááŒáá·áºááá¯ááºáá¬ážááŸááºážááᯠáá±áá¬ááá¯ááºážááœáẠá¡áá¯á¶ážááŒá¯ááááºááŒá áºáááºá
ááŒáá·áºáá±ááá·áºá áá áºááᯠá ááºážáááºááŒááºážááŸáá·áºáááºáááºááá±á¬á áá»áœááºá¯ááºááá¯á·ááẠáá±á«ááºážá ááºá ááºážáááºááŒááºážááá¯á·áááœá±á·áá® á¡á áááºá¡ááá¯ááºážá¡á¬ážáá¯á¶ážááœáẠáá°áá áºá á áºáá±ážááŸá¯áá»á¬ážááŸááááºáᯠáá»áœááºá¯ááºááá¯á·áá°ááá«áááºá (áá»áœááºá¯ááºááá¯á·á á á áºáá±ážááŸá¯ááááºáá»á¬ážááᯠruntime ááœáẠáá±á«ááºážááá·áºááá¯ááºáááºá á ááºážáááºáá²á¡ááá·áºááŸáá·áº runtime ááœáẠáááºáá°áááºáá»áŸáá±á¬ á á¬ááŒáá·áºááá¯ááºá¡á á¯áá áºáá¯ááá¯áááºáž áá±ážááá«áááºá)
áá±á«ááºážá ááºá á áºáá±ážááŸá¯áá»á¬ážááŸáá·áº áá¯ááºáá±á¬ááºáá±á¬á¡áá«á node á¡á¬ážáá¯á¶ážááŸá áá±áá¬ááá¯ááºážááœáẠáá°áá®áá±á¬ classpath ááᯠá¡áá¯á¶ážááŒá¯ááẠáááŒá¬áá ááá¯ááá¯ááœááºáá°áááºá áá»áœááºá¯ááºááá¯á·áá¯ááºáááá·áºá¡áá¬ááŸá¬ áá°áá®áá±á¬ classpath ááᯠruntime ááœááºá¡áá¯á¶ážááŒá¯ááŒá±á¬ááºážáá±áá»á¬á á±áááºááŒá áºáááºá (ááœá²ááŒá¬ážáá±á¬ node áá»á¬ážááᯠááœá²ááŒá¬ážáá±á¬ classpaths áá»á¬ážááŒáá·áº áá¯á¶ážáá¯á¶ážáá»á¬ážáá»á¬áž áá¯ááºáá±á¬ááºááá¯ááºáá±á¬áºáááºážá áááºážááẠá¡áá¯á¶ážá á¯á¶ááœá²á·á ááºážáá¯á¶ááœá²á·á ááºážáá¯á¶ááŸáá·áº á¡áá¯á¶ážáá»ááŒááºážááŸáá·áº áá±á«ááºážá ááºážááŒááºážááá¯ááºáᬠá ááºážáááºááŸá¯áá»á¬ážááœáẠááŸá¯ááºááœá±ážááŸá¯ááá¯á·ááᯠááá¯ážá á±áá«áááºá) á€ááá¯á·á áºááááºááœááºáá»ááºá¡ááœááºá áá»áœááºá¯ááºááá¯á·ááẠnode áá»á¬ážá¡á¬ážáá¯á¶áž áá°áá®áá±á¬ classpath ááᯠá¡áá¯á¶ážááŒá¯áááºáᯠáá°ááá«áááºá
ááœá²á·á
ááºážááŸá¯áá¯á¶á
á¶ááẠá¡ááá®áá±ážááŸááºážááŸáá·áºá¡áá° ááŒá±á¬ááºážáá²áá¬áááºá áá»áœááºá¯ááºááá¯á·ááẠáááá¯ááááºááá·áºáá²ááŒá±á¬ááºážáá²ááŸá¯á¡ááá·áºáá»á¬ážááᯠááœá²ááŒá¬ážáááºááŸááºááẠáá¬ážááŸááºážáá»á¬ážááᯠá¡áá¯á¶ážááŒá¯áá«áááºá ááœá²á·á
ááºážááŸá¯áá¯á¶á
á¶á¡áá»áá¯ážáá»áá¯ážááá¯áááºáž ááœá²ááŒá¬ážáááºááŸááºááẠáá¯áá¹ááááŸááá¯á¶ááááºá ááŒá®ážáááºááŸáá·áº áá¬ážááŸááºážááááºážáá»á¯ááºááŸá¯á
áá
áºááœáẠááœá²á·á
ááºážááŸá¯áá¯á¶á
á¶ááᯠááá¯ááºááá¯ááºááá·áºáá«á áá¯ááºáá¯ááºáá±ážááœáẠááœá²á·á
ááºážááŸá¯áá¯á¶á
á¶áá
áºáá¯áááºážáá¬ááŸááá«áá áá¬ážááŸááºážáá¶áá«ááºááᯠááá¯ážááá¯ážááŸááºážááŸááºáž á¡áá¯á¶ážááŒá¯ááá¯ááºáá«áááºá áá¯ááºáá¯ááºááŸá¯ á
á¶ááá°áá¬áá»á¬ážá
áœá¬ááᯠá¡áá¯á¶ážááŒá¯áá«á áá»á¬ážá
áœá¬ ááá¯á¡ááºáááºááŒá
áºáááºá
ááœá²á·á
ááºážááŸá¯á¡ááá¯ááºážá¡áááºáá»á¬ážááŸáá·áº áá¬ážááŸááºážá¡ááŒáẠáá±á¬ááºáááºá¡ááœáŸááºážáá
áºáᯠ(á¥ááá¬á áá¬áááœá²á¡áááº)á á€áááºážááŒáá·áº áá»áœááºá¯ááºááá¯á·ááẠáááá»áá±á¬ááœá²á·á
ááºážáá¯á¶ááᯠááŸááºážááŸááºážáááºážáááºážááááŸáááá¯ááºáááºááŒá
áºáááºá ááœá²á·á
ááºážááŸá¯áááºááŸááºááŸá¯áá
áºáá¯á
á®ááẠááŒáá·áºáá±áá¬ážáá±á¬ nodeáá»á¬ážá ááááºáááºážáá»á¬ážá ááŒááºáá¡áááºážá¡ááŒá
áºáá»á¬ážááŸáá·áº á
á¬ááŒáá·áºááá¯ááºáá¬ážááŸááºážáá»á¬ážá áá®ážááŒá¬ážáá±á«ááºážá
ááºááŸá¯áá
áºáá¯ááŸáá·áº áááºááá¯ááºáá«áááºá á€ááá¯á·á
áºááááºááœááºáá»ááºáá»á¬ážá¡ááœáẠáá»áœááºá¯ááºááá¯á·ááẠá¡ááá¯ááºážá¡áááºáá
áºáá¯áá¬ááŸááááºáᯠáá»áœááºá¯ááºááá¯á·áá°ááááºááŒá
áºááŒá®ážá á¡á
áẠ(1.2.3) ááŒá¬ážáá¬ážáá±á¬ ááááºážáá¯á¶ážáá¯á¶ážááŒáá·áº áá¯á¶ááŸááºáá¯á¶á
á¶ááŒáá·áº ááœá²á·á
ááºážááŸá¯áá¯á¶á
á¶ááᯠááœá²ááŒá¬ážáááºááŸááºááá¯ááºáá«áááºá
áá±ááºáá
áºáááºáááºážáá»ááºáá»á¬ážááœááºá ááœá²á·á
ááºážááŸá¯ááá¯ááºáá»á¬ážááᯠááá¯ááºááá¯ááºáááºáá®ážáá²áá«áááºá ááŒáá·áºáá»ááºá
ááºá¡ááœááºáž áááºážááá¯á·ááᯠáááŒá¬áá áá¯ááºáá±ážááŒá®áž ááááá±á¬á·áá« (ááá¯á·ááŒá±á¬áá·áº
á€ááá¯á·á áºááœáẠá á¯á ááºážáá¬ážáá±á¬ ááŸá±ážáá±á¬ááºážáá á¹á ááºážáá áºáá¯á¡ááœááºáž ááœá²á·á ááºážááŸá¯áá¯á¶á á¶áá áºáá¯ááᯠááá¯ááºá á¬ážááŒá¯ááá·áº á áááºáá°ážááᯠáá±á·áá¬áá«áááºá
á á¯á ááºážááœá²á·á ááºážááŸá¯
á€ááá¹áááẠstatic compiled configuration á á¥ááá¬ááᯠáá±ážáááºá ááá¯ážááŸááºážáá±á¬áááºáá±á¬ááºááŸá¯ááŸá áºáᯠ- áá²á·áááºáá¶áááºáá±á¬ááºááŸá¯ááŸáá·áº áá²á·áááºáá¶áááºáá±á¬ááºááŸá¯ áááá¯ááºážááá·áºá á€áááºáá±á¬ááºááŸá¯ááŸá áºáá¯á¡áá±á«áºá¡ááŒá±áá¶á á áá áºááœá±ážáá»ááºááŸá¯ááŸá áºáá¯ááᯠá á¯á ááºážáá¬ážáááºá ááœá±ážáá»ááºááŸá¯áá áºáá¯ááœááºá áááºáá±á¬ááºááŸá¯ááŸá áºáá¯áá¯á¶ážááẠáá°áá®áá±á¬ node áá±á«áºááœááºááŸáááŒá®áž á¡ááŒá¬ážááœá±ážáá»ááºááŸá¯áá áºáá¯ááœáẠ- ááá°áá®áá±á¬ node áá»á¬ážááœáẠáááºááŸááááºá
áá¯á¶ááŸááºá¡á¬ážááŒáá·áº ááŒáá·áºáá±ááá·áºá
áá
áºááœáẠnode á¡áá»á¬ážá¡ááŒá¬ážáá«ááŸááááºá á¡áá»áá¯ážá¡á
á¬ážá¡áá»áá¯á·ááááºááá¯ážáá»á¬ážááᯠá¡áá¯á¶ážááŒá¯á node áá»á¬ážááá¯ááœá²ááŒá¬ážááá¯ááºáááºá NodeId
:
sealed trait NodeId
case object Backend extends NodeId
case object Frontend extends NodeId
ááá¯á·ááá¯ááº
case class NodeId(hostName: String)
ááá¯á·ááá¯ááºáááº
object Singleton
type NodeId = Singleton.type
Nodes áá»á¬ážááẠá¡áá»áá¯ážáá»áá¯ážáá±á¬ á¡áááºážááá¹ááá»á¬ážááᯠáá¯ááºáá±á¬ááºáááºá áááºážááá¯á·ááẠáááºáá±á¬ááºááŸá¯áá»á¬ážááᯠáá¯ááºáá±á¬ááºááŒááŒá®áž TCP/HTTP áá»áááºáááºááŸá¯áá»á¬ážááᯠáááºážááá¯á·ááŒá¬ážááœáẠáááºáá±á¬ááºááá¯ááºáááºá
TCP áá»áááºáááºááŸá¯ááᯠáá±á¬áºááŒááẠáá»áœááºá¯ááºááá¯á·ááẠá¡áááºážáá¯á¶áž ááááºáááºážáá¶áá«ááºáá áºáᯠááá¯á¡ááºáá«áááºá client ááŸáá·áº server ááŸá áºáá¯áá¯á¶ážááẠáá°áá®áá±á¬áááá¯ááá¯áá±á¬ááᯠá¡áá¯á¶ážááŒá¯áá±ááŒá±á¬ááºáž áá±áá»á¬á á±ááẠá¡ááá¯áá« port ááœáẠáá¶á·ááá¯ážáá¬ážáá±á¬ áááá¯ááá¯áá±á¬ááᯠáá±á¬ááºááŒááºáááºááá¯áá«áááºá á¡á±á¬ááºáá±á¬áºááŒáá«á¡áááºážááᯠá¡áá¯á¶ážááŒá¯á áá»áááºáááºááŸá¯ááᯠáá±á¬áºááŒáá«áááºá
case class TcpEndPoint[Protocol](node: NodeId, port: Port[Protocol])
áááºááŸá¬ Port
- ááááºážááŒáá·áºáá
áºáá¯áá»áŸáᬠInt
áááºáá¶ááá¯ááºáá±á¬áááºááá¯ážáá»á¬ážá á¡ááœá¬á¡áá±ážááᯠááœáŸááºááŒáááº-
type PortNumber = Refined[Int, Closed[_0, W.`65535`.T]]
ááá·áºá ááºáá±á¬á¡áá»áá¯ážá¡á á¬ážáá»á¬áž
á
á¬ááŒáá·áºááá¯ááºááá¯ááŒáá·áºáá«á
HTTP (REST) ââââáááá¯ááá¯áá±á¬áá»á¬ážá¡ááœááºá ááááºáááºážáá¶áá«ááºá¡ááŒááºá áá»áœááºá¯ááºááá¯á·ááẠáááºáá±á¬ááºááŸá¯á¡ááœáẠáááºážááŒá±á¬ááºážááá¯áááºáž ááá¯á¡ááºááá¯ááºáááº-
type UrlPathPrefix = Refined[String, MatchesRegex[W.`"[a-zA-Z_0-9/]*"`.T]]
case class PortWithPrefix[Protocol](portNumber: PortNumber, pathPrefix: UrlPathPrefix)
Phantom á¡áá»áá¯ážá¡á á¬ážáá»á¬áž
compile time ááœáẠprotocol ááá¯ááœá²ááŒá¬ážáááºááŸááºáááºá class á¡ááœááºážá¡áá¯á¶ážáááŒá¯áá±á¬ type parameter ááá¯á¡áá¯á¶ážááŒá¯áááºá á€áá¯á¶ážááŒááºáá»ááºááẠruntime ááœáẠprotocol instance ááá¯á¡áá¯á¶ážáááŒá¯áá±á¬ááŒá±á¬áá·áºááŒá áºáááºá ááá¯á·áá±á¬áº compiler á០protocol compatibility ááá¯á á áºáá±ážá á±ááá¯áá«áááºá áááá¯ááá¯áá±á¬ááᯠáááºááŸááºááŒááºážááŒáá·áºá áá»áœááºá¯ááºááá¯á·ááẠááŸá®ááá¯ááŸá¯á¡ááŒá Ạáááá·áºáá»á±á¬áºáá±á¬ áááºáá±á¬ááºááŸá¯ááᯠááŒááºáááºážááá¯ááºáááºááá¯ááºáá±á
áá¯á¶áááá¯ááá¯áá±á¬áá»á¬ážáá²ááŸáá áºáá¯ááẠJson áá¶áá«ááºá ááºá¡ááá¯áẠREST API ááŒá áºáááºá
sealed trait JsonHttpRestProtocol[RequestMessage, ResponseMessage]
áááºááŸá¬ RequestMessage
- áá±á¬ááºážááá¯ááŸá¯á¡áá»áá¯ážá¡á
á¬ážá ResponseMessage
- áá¯á¶á·ááŒááºááŸá¯á¡áá»áá¯ážá¡á
á¬ážá
áá»áœááºá¯ááºááá¯á· ááá¯á¡ááºáá±á¬ áá±á¬áºááŒáá»ááºá áááá»ááŸá¯ááᯠáá±ážááá·áº á¡ááŒá¬ážáá±á¬ áááá¯ááá¯áá±á¬ áá±á¬áºááŒáá»ááºáá»á¬ážááᯠáá»áœááºá¯ááºááá¯á· á¡áá¯á¶ážááŒá¯ááá¯ááºáá«áááºá
á€ááá¯á·á áºááááºááœááºáá»ááºá¡ááœááºá áá»áœááºá¯ááºááá¯á·ááẠáááá¯ááá¯áá±á¬áááá¯ážááŸááºážáá±á¬áá¬ážááŸááºážááᯠá¡áá¯á¶ážááŒá¯áá«áááº-
sealed trait SimpleHttpGetRest[RequestMessage, ResponseMessage]
á€ááœáẠáá±á¬ááºážááá¯áá»ááºááẠurl ááœááºááá·áºááœááºážáá¬ážáá±á¬ á á¬ááŒá±á¬ááºážááŒá áºááŒá®áž áá¯á¶á·ááŒááºááŸá¯ááẠHTTP áá¯á¶á·ááŒááºááŸá¯áááá¯ááºáááºááŸá ááŒááºáá±ážááá·áºá á¬ááŒá±á¬ááºážááŒá áºáááºá
áááºáá±á¬ááºááŸá¯ááœá²á·á
ááºážáá¯á¶á¡á¬áž áááºáá±á¬ááºááŸá¯á¡áááºá ááááºáááºážáá»á¬ážááŸáá·áº ááŸá®ááá¯ááŸá¯áá»á¬ážááŒáá·áº áá±á¬áºááŒáá¬ážáá«áááºá á€á¡áá¬áá»á¬ážááᯠScala ááœáẠáááºážáááºážáá»á¬ážá
áœá¬ááŒáá·áº ááá¯ááºá
á¬ážááŒá¯ááá¯ááºááẠ(á¥ááá¬á HList
-sá á¡áá¹ááá¬áááºá¹áá»á¬ áá±áá¬á¡áá»áá¯ážá¡á
á¬ážáá»á¬áž)á á€ááá¯á·á
áºááááºááœááºáá»ááºá¡ááœááºá áá»áœááºá¯ááºááá¯á·ááẠCake Pattern ááá¯á¡áá¯á¶ážááŒá¯ááŒá®áž module áá»á¬ážááá¯á¡áá¯á¶ážááŒá¯á ááá¯ááºá
á¬ážááŒá¯áá«áááºá trait
'ov. (ááááºáá¯áá·áºáá¯á¶á
á¶ááẠá€áá»ááºážáááºááŸá¯á ááá¯á¡ááºáá±á¬ á¡á
áááºá¡ááá¯ááºážáá
áºáá¯ááá¯ááºáá«á áááºážááẠááŒá
áºááá¯ááºáá»á±ááŸááá±á¬ á¡áá±á¬ááºá¡áááºáá±á¬áºááŸá¯áá
áºáá¯ááŒá
áºáááºá)
áááºáá±á¬ááºááŸá¯áá»á¬ážááŒá¬ážááœáẠááŸá®ááá¯á¡á¬ážáá¬ážááŸá¯ááᯠááááºáááºážáá»á¬ážááŒááºááá¯á·ááá·áº áááºážáááºážáá»á¬ážá¡ááŒá
Ạááá¯ááºá
á¬ážááŒá¯ááá¯ááºáááºá EndPoint
á¡ááŒá¬áž node áá»á¬ážá
type EchoProtocol[A] = SimpleHttpGetRest[A, A]
trait EchoConfig[A] extends ServiceConfig {
def portNumber: PortNumber = 8081
def echoPort: PortWithPrefix[EchoProtocol[A]] = PortWithPrefix[EchoProtocol[A]](portNumber, "echo")
def echoService: HttpSimpleGetEndPoint[NodeId, EchoProtocol[A]] = providedSimpleService(echoPort)
}
echo áááºáá±á¬ááºááŸá¯áá áºáá¯áááºáá®ážáááºá áááºááá¯á¡ááºááá»áŸááŸá¬ ááá¯á·ááºáá¶áá«ááºáá áºáá¯ááŒá áºááŒá®áž ááá¯á·ááºááẠecho áááá¯ááá¯áá±á¬ááᯠáá¶á·ááá¯ážáá±ážááŒá±á¬ááºáž ááœáŸááºááŒáá»ááºáá áºáá¯ááŒá áºáááºá áááá»áá²á· ááááºáááºážáá áºáá¯ááᯠáá»áœááºáá±á¬áºááá¯á· áááºááŸááºááá¯á· áááá¬ááŒá±á¬áá·áº... á ááá¯ááºááá¹ááá¬áá»á¬ážááẠááá·áºá¡á¬áž á¡áá±á¬ááºá¡áááºááá±á¬áºáá² áááºážáááºážáá»á¬áž ( abstract method ) ááᯠááŒá±áá¬ááá¯ááºá á±áá«áááºá á€ááá á¹á ááœááºá ááœááºááá áºááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááá¯áááºáá®ážáá±á¬á¡áá«á á á¯á ááºážáá°ááẠáá»áœááºá¯ááºááá¯á·á¡á¬áž abstract method ááá¯á¡áá±á¬ááºá¡áááºáá±á¬áºáááºááŸáá·áº port áá¶áá«ááºáá áºáá¯áá±ážáááºááá¯á¡ááºáááºá áá»áœááºá¯ááºááá¯á·ááẠáááºážáááºážááᯠá¡áá±á¬ááºá¡áááºáá±á¬áºááŒá®ážááŒá áºáá±á¬ááŒá±á¬áá·áº áááá»áá±á¬ááœá²á·á ááºážááŸá¯áá áºáá¯ááᯠáááºáá®ážáá±á¬á¡áá«á áá»áœááºá¯ááºááá¯á·ááẠááá°áá®áá±á¬ááááºáááºážáá áºáá¯ááᯠáááºááŸááºááááá«á áá°áááºážáááºááá¯ážááᯠá¡áá¯á¶ážááŒá¯áá«áááºá
áááá¯ááºážááá·áºááœá²á·á ááºážáá¯á¶á áá áºááœáẠáá»áœááºá¯ááºááá¯á·ááẠáá²á·áááºáá¶áááºáá±á¬ááºááŸá¯á¡áá±á«áº ááŸá®ááá¯ááŸá¯ááᯠááŒá±ááŒá¬áááº-
trait EchoClientConfig[A] {
def testMessage: String = "test"
def pollInterval: FiniteDuration
def echoServiceDependency: HttpSimpleGetEndPoint[_, EchoProtocol[A]]
}
ááŸá®ááá¯ááŸá¯ááẠáááºááá¯á·ááá·áºáááºáá±á¬ááºááŸá¯ááŸáá·áº á¡áá»áá¯ážá¡á
á¬ážáá°áááºá echoService
. á¡áá°ážáááŒáá·áºá áá²á·áááºáá¶áá±á¬ááºáááºáá»á¬ážááœáẠáá»áœááºá¯ááºááá¯á·ááẠáá°áá®áá±á¬áááá¯ááá¯áá±á¬ááᯠááá¯á¡ááºáááºá ááá¯á·ááŒá±á¬áá·áºá áááºáá±á¬ááºááŸá¯ááŸá
áºáá¯ááᯠáá»áááºáááºááá·áºá¡áá« á¡áá¬á¡á¬ážáá¯á¶ážááẠááŸááºáááºááŒá±á¬ááºáž áá»áœááºá¯ááºááá¯á· á
áááºáá»ááá¯ááºáá«áááºá
áááºáá±á¬ááºááŸá¯áá»á¬áž á¡áá±á¬ááºá¡áááºáá±á¬áºááŒááºážá
áááºáá±á¬ááºááŸá¯ááᯠá
áááºáááºááŸáá·áº áááºááẠáá¯ááºáá±á¬ááºáá»ááºáá
áºáᯠááá¯á¡ááºáá«áááºá (á
ááºážáááºááŒááºážá¡ááœáẠáááºáá±á¬ááºááŸá¯áá
áºáá¯á¡á¬áž áááºááá·áºááẠá
áœááºážáááºááẠá¡áá±ážááŒá®ážáá«áááºá) áááºáá¶á ááá¯áá²á·ááá¯á·áá±á¬ á¡ááºá¹áá«áááºááᯠá¡áá±á¬ááºá¡áááºáá±á¬áºáááºá¡ááœáẠááœá±ážáá»ááºá
áá¬áá»á¬ážá
áœá¬ááŸáááẠ(á¥ááá¬á ááœá²á·á
ááºážááŸá¯áá¯á¶á
á¶á¡áá±á«áºá¡ááŒá±áá¶á á¡áá»áá¯ážá¡á
á¬ážá¡áááºážáá»á¬ážááᯠáá»áœááºá¯ááºááá¯á·á¡áá¯á¶ážááŒá¯ááá¯ááºáááº)á áá®ááá¯á·á
áºáá²á·áááºááœááºáá»ááºá¡ááœáẠáá»áœááºáá±á¬áºááá¯á·á Cake Pattern ááá¯áá¯á¶ážáá«áááºá á¡áááºážáá
áºáá¯ááᯠá¡áá¯á¶ážááŒá¯á áááºáá±á¬ááºááŸá¯ááᯠááá¯ááºá
á¬ážááŒá¯áá«áááºá cats.Resource
, áá¬ááŒá
áºááá¯á·áá²ááá¯áá±á¬á· á€á¡áááºážááẠááŒá¿áá¬áá»á¬ážááŸááá±á¬á¡áá«ááœáẠá¡áááºážá¡ááŒá
áºáá»á¬ážááᯠáá±ážáááºážá
áœá¬ ááœáŸááºáá±ážááẠá¡á¬ááá¶áá»ááºáá±ážáá¬ážááŒá®ážááŒá
áºáááºá á¡áááºážá¡ááŒá
áºáá
áºáá¯áááŸááááºá áá»áœááºá¯ááºááá¯á·ááẠááœá²á·á
ááºážááŸá¯áá¯á¶á
á¶ááŸáá·áº á¡áááºááá·áºáá¯ááºáá¬ážáá±á¬ runtime á¡ááŒá±á¬ááºážá¡áá¬ááᯠáá¶á·ááá¯ážáá±ážáááºááá¯á¡ááºáááºá áááºáá±á¬ááºááŸá¯á
áááºááŒááºážáá¯ááºáá±á¬ááºáá»ááºááẠá€áá²á·ááá¯á·ááŒá
áºááá¯ááºáááº-
type ResourceReader[F[_], Config, A] = Reader[Config, Resource[F, A]]
trait ServiceImpl[F[_]] {
type Config
def resource(
implicit
resolver: AddressResolver[F],
timer: Timer[F],
contextShift: ContextShift[F],
ec: ExecutionContext,
applicative: Applicative[F]
): ResourceReader[F, Config, Unit]
}
áááºááŸá¬
Config
â á€áááºáá±á¬ááºááŸá¯á¡ááœáẠááœá²á·á ááºážááŸá¯áá¯á¶á á¶AddressResolver
- á¡ááŒá¬áž node áá»á¬ážá ááááºá á¬áá»á¬ážááᯠááááŸáááá¯ááºá á±ááá·áº runtime object áá áºáᯠ(á¡á±á¬ááºááœááºááŒáá·áºáá«)
á
á¬ááŒáá·áºááá¯ááºá០á¡ááŒá¬ážá¡áá»áá¯ážá¡á
á¬ážáá»á¬áž cats
:
F[_]
- á¡áá»áá¯ážáááºáá±á¬ááºááŸá¯á¡áá»áá¯ážá¡á á¬áž (á¡ááá¯ážááŸááºážáá¯á¶ážááá á¹á ááœááºF[A]
function áá áºáá¯áá²ááŒá áºááá¯ááºáá«áááºá() => A
. áá® post ááŸá¬ áá»áœááºáá±á¬áºáá¯á¶ážáá«áááºácats.IO
.)Reader[A,B]
- áá¯ááºáá±á¬ááºáá»ááºááŸáá·áº á¡áááá¹áá«ááºáá°áááºáA => B
cats.Resource
- ááá°ááŒá®áž áá¯ááºááœáŸááºááá¯ááºáá±á¬ á¡áááºážá¡ááŒá áºáá áºáá¯Timer
- timer (áááᬠá¡áááºáá»á±á¬áºá á±ááŒá®áž á¡áá»áááºá¡ááá¯ááºážá¡ááŒá¬ážáá»á¬ážááᯠááá¯ááºážáá¬ááá¯ááºáááº)ContextShift
- analogExecutionContext
Applicative
- áá áºáŠážáá»ááºážá á®á¡áá»áá¯ážáááºáá±á¬ááºááŸá¯áá»á¬áž (monad áá®ážáá«áž) ááá¯áá±á«ááºážá ááºááœáá·áºááŒá¯áá±á¬á¡áá»áá¯ážáááºáá±á¬ááºááŸá¯á¡áá»áá¯ážá¡á á¬ážá¡áááºážá ááá¯ááá¯ááŸá¯ááºááœá±ážáá±á¬ application áá»á¬ážááœááºá¡áá¯á¶ážááŒá¯áááºááá¯áá±á¬ááºážáá¯á¶ááááºáMonad
/ConcurrentEffect
.
á€áá¯ááºáá±á¬ááºáá»áẠáááºááŸááºááᯠá¡áá¯á¶ážááŒá¯á áá»áœááºá¯ááºááá¯á·ááẠáááºáá±á¬ááºááŸá¯áá»á¬ážá áœá¬ááᯠá¡áá±á¬ááºá¡áááºáá±á¬áºááá¯ááºáá«áááºá á¥ááá¬á áá¬ááŸááá¯ááºáá²á· áááºáá±á¬ááºááŸá¯áá áºáá¯á
trait ZeroServiceImpl[F[_]] extends ServiceImpl[F] {
type Config <: Any
def resource(...): ResourceReader[F, Config, Unit] =
Reader(_ => Resource.pure[F, Unit](()))
}
(ááŒááºá·ááŸá¯áá«á
О
node ááẠáááºáá±á¬ááºááŸá¯áá»á¬ážá áœá¬ááᯠááœáŸáá·áºáááºááá¯ááºáá±á¬ á¡áá¬áá áºáá¯ááŒá áºááẠ(á¡áááºážá¡ááŒá áºáá»á¬ážá ááœááºážáááºáá áºáá¯á¡á¬áž ááááºáá¯áá·áºáá¯á¶á á¶ááŒáá·áº á¡á¬ááá¶áá¬ážáááº)á
object SingleNodeImpl extends ZeroServiceImpl[IO]
with EchoServiceService
with EchoClientService
with FiniteDurationLifecycleServiceImpl
{
type Config = EchoConfig[String] with EchoClientConfig[String] with FiniteDurationLifecycleConfig
}
ဠnode á¡ááœáẠááá¯á¡ááºáá±á¬ ááœá²á·á ááºážááŸá¯áá¯á¶á ᶠá¡ááá¡áá»ááᯠáá»áœááºá¯ááºááá¯á·áááºááŸááºáá¬ážááŒá±á¬ááºáž áá»á±ážáá°ážááŒá¯á áááááŒá¯áá«á áááºáá±á¬ááºááŸá¯áá áºáá¯á០ááá¯á¡ááºáá±á¬ ááœá²á·á ááºážááŸá¯áá¯á¶á á¶áá»á¬ážáá²á០áá áºáá¯ááᯠáááºááŸááºááẠáá±á·ááœá¬ážáá«áá á á¯á ááºážááŸá¯ á¡ááŸá¬ážáá áºáᯠááŸááááá·áºáááºá ááá¯á·á¡ááŒááºá áá»áœááºá¯ááºááá¯á·ááẠááá¯á¡ááºáá±á¬áá±áá¬á¡á¬ážáá¯á¶ážááᯠááá·áºáá»á±á¬áºáá±á¬á¡áá»áá¯ážá¡á á¬ážáá¡áá¬ááá¹áá¯á¡áá»áá¯á·ááᯠááá±ážáá«á node áá áºáá¯ááᯠá áááºááá¯ááºáááºááá¯ááºáá±á
áááºáá¶áá°á¡ááẠáá¯á¶ážááŒááºáá»ááº
á¡áá±ážááááºážáá¬áááá¯á· áá»áááºáááºáááºá áá»áœááºá¯ááºááá¯á·ááẠá¡ááŸááºáááẠIP ááááºá á¬áá áºáᯠááá¯á¡ááºáá«áááºá ááááºá á¬ááẠá¡ááŒá¬ážááœá²á·á ááºážááŸá¯áá¯á¶á á¶áá»á¬ážááẠáá±á¬ááºáá»á០áááá¬ááẠááŒá áºááá¯ááºáááºá ááá¯á·ááŒá±á¬áá·áº áá»áœááºá¯ááºááá¯á·ááẠnode ID ááᯠááááºá á¬áá áºáá¯ááá¯á· ááŒá±áá¯á¶ááœáŸááºážáá±ážááá·áº áá¯ááºáá±á¬ááºáá»ááºáá áºáᯠááá¯á¡ááºáá«áááºá
case class NodeAddress[NodeId](host: Uri.Host)
trait AddressResolver[F[_]] {
def resolve[NodeId](nodeId: NodeId): F[NodeAddress[NodeId]]
}
á€áá¯ááºáá±á¬ááºáá»ááºááᯠá¡áá±á¬ááºá¡áááºáá±á¬áºááẠáááºážáááºážáá»á¬ážá áœá¬ááŸááá«áááºá
- áááŒáá·áºáá»ááºáá® ááááºá
á¬áá»á¬ážááᯠáá»áœááºá¯ááºááá¯á·áááá¬áá«áá áá»áœááºá¯ááºááá¯á·ááẠScala áá¯ááºááŒáá·áº áá¯ááºáá¯ááºááá¯ááºáá«áááºá
ááááºá á¬áá»á¬áž ááŒá®ážáá±á¬áẠbuild ááᯠrun áá«á áááºážááẠá ááºážáááºááŸá¯áá»á¬ážááᯠá á¯á ááºážááŒá®áž áá¯ááºáá±á¬ááºáááºááŒá áºáááºá
á€ááá á¹á ááœááºá áá¯ááºáá±á¬ááºáá»ááºááᯠáááºááŒáááºá áœá¬ááááá¯ááºááŒá®áž ááŒá±áá¯á¶á¡ááŒá Ạáá¯ááºááŒáá·áº ááá¯ááºá á¬ážááŒá¯ááá¯ááºáááºáMap[NodeId, NodeAddress]
. - á¡áá»áá¯á·ááá
á¹á
áá»á¬ážááœááºá node á
áááºááŒá®ážáá±á¬ááºááŸáᬠá¡ááŸááºááááºááááºá
á¬ááᯠááááá¯ááºáááºá
á€ááá á¹á ááœááºá áá»áœááºá¯ááºááá¯á·ááẠá¡ááŒá¬áž node áá»á¬ážááŸá±á·ááœáẠáá¯ááºáá±á¬ááºááá·áº âááŸá¬ááœá±ááŸá¯áááºáá±á¬ááºááŸá¯â ááᯠá¡áá±á¬ááºá¡áááºáá±á¬áºááá¯ááºááŒá®áž node áá»á¬ážá¡á¬ážáá¯á¶ážááẠá€áááºáá±á¬ááºááŸá¯ááŸáá·áºá¡áá° á á¬áááºážááœááºážááŒá®áž á¡ááŒá¬áž nodes áá»á¬ážáááááºá á¬áá»á¬ážááᯠáá±á¬ááºážááá¯áááºááŒá áºáááºá - ááŒá¯ááŒááºááá¯á· ááááºá
/etc/hosts
ááá¯á·áá±á¬áẠáááºááŒáá¯áááºáááºááŸááºáá¬ážáá±á¬ hostnames ááá¯áá¯á¶ážááá¯ááºááẠ(áá²á·ááá¯á·áá±á¬my-project-main-node
Оecho-backend
) ááŸáá·áº á€á¡áááºáá»á¬ážááᯠááá¯ážááŸááºážá áœá¬ áá»áááºáááºáá«á
ááŒáá·áºáá»ááºá ááºá¡ááœááºáž IP ááááºá á¬áá»á¬ážááŸáá·áºá¡áá°á
á€ááá¯á·á
áºááœáẠáá»áœááºá¯ááºááá¯á·ááẠá€ááá
á¹á
áá»á¬ážááᯠá¡áá±ážá
áááºááá·áºááœááºážá
ááºážá
á¬ážáááºááá¯ááºáá«á áá«ááá¯á·á¡ááœááº
á¡áá¯ááºá¥ááá¬áá
áºáá¯ááœááºá node áá»á¬ážá¡á¬ážáá¯á¶ážáááºáá°áá®áá±á¬ IP ááááºá
á¬ááŸááááá·áºááẠ- 127.0.0.1
.
ááá¯á·áá±á¬ááºá áá»áœááºá¯ááºááá¯á·ááẠááŒáá·áºáá±ááá·áºá áá áºá¡ááœáẠááœá±ážáá»ááºá áá¬ááŸá áºáá¯ááᯠá ááºážá á¬ážáááº-
- áááºáá±á¬ááºááŸá¯á¡á¬ážáá¯á¶ážááᯠnode áá áºáá¯ááœáẠáá±áá¬áá»áá¬ážááŒááºážá
- ááŸáá·áº echo áááºáá±á¬ááºááŸá¯ááŸáá·áº echo client ááᯠááá°áá®áá±á¬ node áá»á¬ážááœáẠáááºáá¶áá±á¬ááºááœááºáá±ážááŒááºážá
ááœá²á·á
ááºážááŸá¯áá¯á¶á
á¶
Single node ááœá²á·á ááºážááŸá¯
object SingleNodeConfig extends EchoConfig[String]
with EchoClientConfig[String] with FiniteDurationLifecycleConfig
{
case object Singleton // identifier of the single node
// configuration of server
type NodeId = Singleton.type
def nodeId = Singleton
/** Type safe service port specification. */
override def portNumber: PortNumber = 8088
// configuration of client
/** We'll use the service provided by the same host. */
def echoServiceDependency = echoService
override def testMessage: UrlPathElement = "hello"
def pollInterval: FiniteDuration = 1.second
// lifecycle controller configuration
def lifetime: FiniteDuration = 10500.milliseconds // additional 0.5 seconds so that there are 10 requests, not 9.
}
á¡áá¬ááá¹áá¯ááẠclient ááŸáá·áº server ááŸá
áºáá¯áá¯á¶ážá configuration ááá¯á¡áá±á¬ááºá¡áááºáá±á¬áºáááºá ááŒá¬ážáá¬áááŒá®ážáá±á¬ááºááœáẠá¡áá»áááº-á០ááá¯ááºááá¯ááºááœá²á·á
ááºážááŸá¯á
áá
áºááá¯áááºáž á¡áá¯á¶ážááŒá¯áá«áááºá lifetime
á¡á
á®á¡á
ááºááᯠá¡áá¯á¶ážáááºáá«á (Ctrl-C áááºáááºáž á¡áá¯ááºáá¯ááºááŒá®áž á¡áááºážá¡ááŒá
áºá¡á¬ážáá¯á¶ážááᯠááŸááºáááºá
áœá¬ ááœáŸááºáá±ážáá«áááºá)
áá°áá®áá±á¬ááœá²á·á
ááºážáá¯á¶ááŸáá·áº á¡áá±á¬ááºá¡áááºáá±á¬áºááŸá¯á
ááá¯ááºáá»á¬áž áá«áááºáá±á¬ á
áá
áºáá
áºáá¯ááᯠáááºáá®ážááẠá¡áá¯á¶ážááŒá¯ááá¯ááºáááºá
node configuration ááŸá áºáá¯
object NodeServerConfig extends EchoConfig[String] with SigTermLifecycleConfig
{
type NodeId = NodeIdImpl
def nodeId = NodeServer
override def portNumber: PortNumber = 8080
}
object NodeClientConfig extends EchoClientConfig[String] with FiniteDurationLifecycleConfig
{
// NB! dependency specification
def echoServiceDependency = NodeServerConfig.echoService
def pollInterval: FiniteDuration = 1.second
def lifetime: FiniteDuration = 10500.milliseconds // additional 0.5 seconds so that there are 10 request, not 9.
def testMessage: String = "dolly"
}
á¡áá±ážááŒá®ážáááº! áááºáá±á¬ááºááŸá¯áá»á¬ážááᯠáááºááá¯á·áá»áááºáááºáá¬ážáááºááᯠáááááŒá¯áá«á áá»áœááºá¯ááºááá¯á·ááẠnode áá áºáá¯ááŸáá¯ááºáá±á¬ááºáá±á¬áááºáá±á¬ááºááŸá¯ááᯠá¡ááŒá¬áž node áááŸá®ááá¯ááŸá¯áááºážáááºážááá¯á¡áá±á¬ááºá¡áááºáá±á¬áºááŸá¯á¡ááŒá ẠáááºááŸááºáá«áááºá ááŸá®ááá¯ááŸá¯á¡áá»áá¯ážá¡á á¬ážááᯠcompiler ááŸá á áºáá±ážáá±á¬ááŒá±á¬áá·áºááŒá áºáááºá áááá¯ááá¯áá±á¬ á¡áá»áá¯ážá¡á á¬áž áá«ááŸááááºá áá¯ááºáá±á¬ááºááá·áºá¡áá«á ááŸá®ááá¯ááŸá¯ááœáẠááŸááºáááºáá±á¬ áá áºááŸááºá¡ááŸááºá¡áá¬áž ID áá«ááŸááá«áááºá á€á¡á á®á¡á á¥áºááŒá±á¬áá·áºá áá»áœááºá¯ááºááá¯á·ááẠááááºáááºážáá¶áá«ááºááᯠáá áºááŒáááºáááá áááºááŸááºáá±ážááŒá®áž ááŸááºáááºáá±á¬ááááºáááºážááᯠáááºááœáŸááºážááẠá¡ááŒá²á¡á¬ááá¶áá«áááºá
á áá áºáá¯á¶ááŸááºááŸá áºáá¯ááᯠá¡áá±á¬ááºá¡áááºáá±á¬áºááŒááºážá
á€ááœá²á·á ááºážáá¯á¶á¡ááœááºá áá»áœááºá¯ááºááá¯á·ááẠááŒá±á¬ááºážáá²ááŒááºážáááŸááá² áá°áá®áá±á¬áááºáá±á¬ááºááŸá¯á¡áá±á¬ááºá¡áááºáá±á¬áºááŸá¯áá»á¬ážááᯠá¡áá¯á¶ážááŒá¯áá«áááºá áá áºáá¯áááºážáá±á¬ ááœá¬ááŒá¬ážáá»ááºááŸá¬ ááᯠáá»áœááºá¯ááºááá¯á·ááœáẠááá°áá®áá±á¬ áááºáá±á¬ááºááŸá¯á¡á á¯á¶áá»á¬ážááᯠá¡áá±á¬ááºá¡áááºáá±á¬áºááá·áº á¡áá¬ááŸá áºáá¯ááŸááááºá
object TwoJvmNodeServerImpl extends ZeroServiceImpl[IO] with EchoServiceService with SigIntLifecycleServiceImpl {
type Config = EchoConfig[String] with SigTermLifecycleConfig
}
object TwoJvmNodeClientImpl extends ZeroServiceImpl[IO] with EchoClientService with FiniteDurationLifecycleServiceImpl {
type Config = EchoClientConfig[String] with FiniteDurationLifecycleConfig
}
ááááá¯á¶áž node ááẠáá¬áá¬ááᯠá¡áá±á¬ááºá¡áááºáá±á¬áºááŒá®áž áá¬áá¬ááœá²á·á
ááºážááŸá¯áá¯á¶á
á¶ááá¯áᬠááá¯á¡ááºáááºá áá¯ááá node ááẠclient ááá¯á¡áá±á¬ááºá¡áááºáá±á¬áºááŒá®áž configuration áá¡ááŒá¬ážá¡á
áááºá¡ááá¯ááºážááá¯á¡áá¯á¶ážááŒá¯áááºá ááá¯á·á¡ááŒáẠnode ááŸá
áºáá¯áá¯á¶ážáááºáá
áºáááºáá¬á
á®áá¶ááá·áºááœá²ááŸá¯ááá¯á¡ááºáááºá áá¬áᬠNode ááẠáááºážááᯠáááºááá·áºáááºá¡áá á¡ááá·áºá¡áááºáááŸá áá¯ááºáá±á¬ááºáááºá SIGTERM
'omá á¡áá»áááºá¡áááºááŒá¬ááŒá®ážáá±á¬áẠclient node ááẠáááºá
á²ááœá¬ážáá«áááºá á
ááºáá®áá®áá¬á
á¡ááœá±ááœá±ááœá¶á·ááŒáá¯ážááá¯ážáááºáá±ážáá¯ááºáááºážá ááº
á€ááœá²á·á ááºážáá¯á¶á áá áºáá»ááºážáááºááŸá¯ááẠá¡áá¯á¶ážá á¯á¶ááœá¶á·ááŒáá¯ážááá¯ážáááºááŸá¯áá¯ááºáááºážá ááºá¡áá±á«áº áááºááá¯á·á¡áá»áá¯ážáááºáá±á¬ááºáááºááᯠááŒáá·áºááŒáá«á áá¯á·á
ááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááᯠáá»ááºáá¯ááºáá»á¬ážááŸáá·áºá¡áá° á á¯á ááºážááŒá®áž ááŸá±ážáá±á¬ááºážáá á¹á ááºáž (.jar) ááᯠáá¯ááºáá±ážáááºááŒá áºáááºá ááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááᯠáá®ážááŒá¬áž ááŸá±ážáá±á¬ááºážáá á¹á ááºážáá áºáá¯ááœáẠááá·áºááœááºážááŒááºážááẠá¡áááá¹áá¬ááºááŸááá¯á¶ááááºá á¡áááºááŒá±á¬áá·áºááá¯áá±á¬áº áá»áœááºá¯ááºááá¯á·ááẠáá°áá®áá±á¬áá¯ááºááá¯á¡ááŒá±áá¶á ááœá²á·á ááºážááŸá¯á¡áá»á¬ážá¡ááŒá¬ážááŸáááá¯ááºáá±á¬ááŒá±á¬áá·áºááŒá áºáááºá áá áºáááºá ááœá²ááŒá¬ážáá±á¬ááœá²á·á ááºážáá¯á¶á¡ááá¯ááºážá¡áááºáá»á¬ážááŸáá·áº áááºááá¯ááºááá·áº ááŸá±ážáá±á¬ááºážáá á¹á ááºážáá»á¬ážááᯠáá¯ááºáá¯ááºááẠááŒá áºááá¯ááºáááºá áááºááŸááºáá¬ážáá±á¬ á á¬ááŒáá·áºááá¯ááºáá»á¬ážá áá¬ážááŸááºážáá»á¬ážá¡áá±á«áº ááŸá®ááá¯á¡á¬ážáá¬ážááŸá¯áá»á¬ážááᯠá á®á ááºááœá²á·á ááºážááŸá¯ááŸáá·áºá¡áá° ááááºážáááºážáá¬ážáᬠáááºážáá¬ážááŸááºážáá»á¬ážááᯠáááºáááºá¡áá¯á¶ážááŒá¯ááẠáá¯á¶ážááŒááºááá·áºá¡áá«ááá¯ááºáž á€áá¬ážááŸááºážáá»á¬ážááᯠáá¬áá áẠááááºážáááºážáá¬ážáááºá
áááºááá·áºááœá²á·á
ááºážáá¯á¶ááŒá±á¬ááºážáá²ááŸá¯áááᯠáá¯ááºááŒá±á¬ááºážáá²ááŸá¯á¡ááŒá
áºááá¯á· ááŒá±á¬ááºážáá²ááœá¬ážáááºá ááá¯á·ááŒá±á¬áá·áºá áá
áºáá¯áá»ááºážá
á®
ááŒá±á¬ááºážáá²ááŸá¯á¡á¬áž áá¯á¶ááŸááºá¡áááºá¡ááœá±ážá¡á¬ááá¶ááŸá¯áá¯ááºáááºážá
ááºááŒáá·áº á¡áá»á¯á¶ážáááºáááº-
bug tracker á០áááºááŸáẠ-> PR -> review -> áááºááá¯ááºáᬠá¡ááá¯ááºážá¡áááºáá»á¬áž -> ááŸáá·áº áá±á«ááºážá
ááºážáá«á
áá±á«ááºážá
ááºážááŒááºáž -> ááŒáá·áºáá»ááºááŒááºážá
á á¯á ááºážáá¬ážáá±á¬ ááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááᯠá¡áá±á¬ááºá¡áááºáá±á¬áºááŒááºážá á¡áááá¡áá»áá¯ážáááºáá»á¬ážááŸá¬-
-
ááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááẠááŒáá·áºáá±á áá áºá node áá»á¬ážá¡á¬ážáá¯á¶ážááœáẠáááááºáááºážááŒá áºáááá·áºáááºá á¡áááºááŒá±á¬áá·áºááá¯áá±á¬áº node á¡á¬ážáá¯á¶ážááẠá¡áááºážá¡ááŒá áºáá áºáá¯áááºážá០áá°áá®áá±á¬ configuration ááá¯áááºáá¶áááŸááá±á¬ááŒá±á¬áá·áºááŒá áºáááºá
-
node áá»á¬ážáá²ááŸáá áºáá¯áᬠconfiguration ááá¯ááŒá±á¬ááºážáááºá¡áááºá¡áá²ááŸááááºá ááá¯á·ááŒá±á¬áá·áº âááœá²á·á ááºážáá¯á¶ áá»á¶á·ááœáá·áºááŒááºážâ ááẠáááŒá áºááá¯ááºáá±á
-
ááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááœáẠáá±ážáááºáá±á¬ááŒá±á¬ááºážáá²ááŸá¯áá»á¬ážááŒá¯áá¯ááºááẠááá¯ááá¯áááºáá²áá¬áááºá
-
á¡áá¯á¶ážá á¯á¶ ááœá¶á·ááŒáá¯ážááá¯ážáááºááŸá¯ áá¯ááºáááºážá ááºá áá áºá áááºáá áºááá¯ááºážá¡áá±ááŒáá·áº ááœá²á·á ááºážááŸá¯ááá¯ááºáᬠááŒá±á¬ááºážáá²ááŸá¯á¡áá»á¬ážá á¯ááẠááŒá áºáá±á«áºáá¬áááºááŒá áºááŒá®áž ááŒááºáááºáá¯á¶ážáááºááẠááá¯á¡ááºáááºááŒá áºáááºá
áá¯ááºáá¯ááºááŸá¯ááœá²á·á ááºážáá¯á¶áá¯á¶á á¶ááᯠááááºážáááºážááẠáá®ážááŒá¬ážááá¯ááŸá±á¬ááºááŸá¯áá áºáᯠááá¯á¡ááºáá«ááá¬ážá á€ááœá²á·á ááºážáá¯á¶ááœáẠáá»áœááºá¯ááºááá¯á· áááºáá±á¬ááºááœáá·áºááᯠááá·áºáááºááá¯ááá·áº á áá¬ážááŸááºáá»á¬ážááŸáá·áº á¡ááŒá¬áž á¡áá±ážááŒá®ážáá±á¬ á¡áá»ááºá¡áááºáá»á¬áž áá«áááºááá¯ááºáááºá áááºážááá¯á¡ááŒá±áá¶á áá®ážááŒá¬áž repository ááœáẠáá±á¬ááºáá¯á¶ážááœá²á·á ááºážáá¯á¶ááᯠááááºážáááºážááẠá¡áááá¹áá¬ááºááŸááá¯á¶ááááºá ááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááᯠá¡ááá¯ááºážááŸá áºááá¯ááºážááœá²ááá¯ááºáááºâáá áºááá¯ááºážááẠá¡áá»á¬ážáá°ááŸá¬áááºáá±á¬ááºááá¯ááºáá±á¬ ááœá²á·á ááºážááŸá¯áá¯á¶á á¶áááºáááºáá»á¬áž ááŸáá·áº ááá·áºáááºáááºáááºáá»á¬ážáá«ááŸááá±á¬ á¡ááá¯ááºážáá áºáá¯áá«ááŸááááºá áááºážááẠáá±á¬á·ááºáá²á¡ááºáá»ááºáá®áá¬á¡áá»á¬ážá á¯á áá¯á¶áááºáááºáá»á¬ážááá¯á· áááºáá±á¬ááºááœáá·áºáááŸáá á±áááºááŒá áºáááºá áá¯á¶áá±áááºááá¯ážáá»á¬ážáá«ááŸááá±á¬ á¡áááºá¡áááºááá¹ááá¬áá»á¬ážááᯠá¡áá¯á¶ážááŒá¯á á€ááœá²ááœááºááŸá¯ááẠááœááºáá°áááºá
ááœá²ááŒá¬ážááŸá¯áá»á¬áž ááŒá áºááá¯ááºáááºá
á á¯á ááºážáá¬ážáá±á¬ ááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááᯠá¡áá»á¬ážá¡á¬ážááŒáá·áº á¡ááŒá¬ážááœá±ážáá»ááºá áá¬á¡áá»áá¯á·ááŸáá·áº ááŸáá¯ááºážááŸááºááŒáá·áºááŒáá«á áá¯á·á
- áá áºááŸááºá ááºáá±á«áºááŸá á á¬áá¬ážááá¯ááºá
- áááá¯áá»á¯ááºááá¯ááºááŸá¯ áá±á¬á·áááºááá¯ážá
ááá¯ážááá¯áẠ(
etcd
/zookeeper
). - áá¯ááºáááºážá ááºááᯠááŒááºáááºá áááºááŒááºážáááŸááá² ááŒááºáááºááœá²á·á ááºážááŒááºáž/ááŒááºáááºá áááºááá¯ááºááá·áº áá¯ááºáááºážá ááºá¡á áááºá¡ááá¯ááºážáá»á¬ážá
- ááŸá±ážáá±á¬ááºážáá á¹á ááºážááŸáá·áº áá¬ážááŸááºážááááºážáá»á¯ááºááŸá¯ááŒááºáááœáẠááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááᯠááááºážáááºážááŒááºážá
á á¬áá¬ážááá¯ááºáá»á¬ážááẠáá±ážáááºáá±á¬ááŒá±á¬ááºážáá²ááŸá¯áá»á¬ážá¡ááœáẠáááá¬áááºááŸá¬ážáá±á¬ áá»á±á¬á·ááŒá±á¬ááºážááŸá¯ááᯠáá±ážáá«áááºá á áá áºá á®áá¶ááá·áºááœá²áá°ááẠá¡áá±ážááááºáž Node ááá¯á·áááºáá±á¬ááºááá¯ááºááŒá®áž ááá·áºáá»á±á¬áºáá±á¬ááá¯ááºáá»á¬ážááᯠá¡ááŒá±á¬ááºážá¡áá²áá»á¬ážááŒá¯áá¯ááºáᬠáááºáá±á¬ááºááŸá¯ááᯠááŒááºáááºá áááºááá¯ááºáááºá ááá¯á·áá±á¬áº á áá áºááŒá®ážáá»á¬ážá¡ááœááºá ááá¯ááá¯á·áá±á¬ ááŒá±á¬ááºážááœááºááŒááºááœááºááẠááŸá áºááá¯ááœááºáááŸááá±á ááŒá±á¬ááºážáá²ááŸá¯áá»á¬ážááẠá¡ááŒá¬ážá áá áºáá»á¬ážááœáẠááŒá±áá¬áá¶ááá¬ážáá²á·áá«á á¡ááŒá±á¬ááºážá¡áá²áá»á¬ážááᯠáááºáá°áá»áŸ ááá¯á¶ážáááºááŒáá«á á¡ááŒá±á¬ááºážá¡áá²áá»á¬ážááᯠáááºáá°á á¡ááá¡áá»ááŒá¯áá¯ááºááŒá®áž áááºááá·áºá¡ááŒá±á¬ááºážááŒá±á¬áá·áºááŒá áºáááºááᯠáá¯á¶ážááŒááºáááºáááºáá²áááºá á¡ááŒá±á¬ááºážá¡áá²áá»á¬ážááᯠáá ááºážáááºáá«á á áá áºá¡á¬áž ááŒáá·áºáá±áá«áá á á®áá¶ááá·áºááœá²áá°ááẠá¡ááŒá¬áž node áá»á¬ážááœáẠáááºááá¯ááºáá±á¬ááŒá±á¬ááºážáá²ááŸá¯ááᯠááŒá¯áá¯ááºááẠáá±á·ááœá¬ážááá¯ááºáááºá
(á
á¯á
ááºážáá¬ážáá±á¬ ááœá²á·á
ááºážááŸá¯áá¯á¶á
á¶ááᯠá¡áá¯á¶ážááŒá¯ááŒááºážááẠá¡áá¬áááºááœáẠá
á¬áá¬ážááá¯ááºáá»á¬ážááᯠá¡áá¯á¶ážááŒá¯ááẠááŒá
áºááá¯ááºááŒá±ááᯠááááºáááºááá¯ááºááŒá±á¬ááºáž ááŸááºáá¬ážáá¬ážááá·áºáá«áááºá áááºážááẠá¡ááœááºáá²á·ááá¯á· á¡áá»áá¯ážá¡á
á¬ážáá° áá¯ááºáá¯ááºáá±ážááá·áº parser ááŸáá·áº validator ááᯠááá·áºááẠáá¯á¶áá±á¬ááºáá«áááá·áºáááºá Config
ááŸáá·áº á
á¬áá¬ážááá¯ááºáá»á¬ážááᯠáááºáá¯á¶ážááá¯ááºáááºá á
á¯á
ááºážááœá²á·á
ááºážááŸá¯á
áá
áºáá
áºáá¯á ááŸá¯ááºááœá±ážááŸá¯ááẠá
á¬áá¬ážááá¯ááºáá»á¬ážááᯠá¡áá¯á¶ážááŒá¯ááá·áº á
áá
áºáá
áºáá¯á ááŸá¯ááºááœá±ážááŸá¯ááẠá¡áááºážáááºáááºážáá±á¬ááŒá±á¬áá·áº áááºážááẠáá»ááºááŒááºážááœáẠá¡á±á¬ááºáá«á¡ááá¯ááºážááŒá
áºáááºá á
á¬áá¬ážááá¯ááºáá»á¬ážááẠá¡ááá¯áá¯áẠááá¯á¡ááºáá«áááºá)
áááá¯áá»á¯ááºááá¯ááºááŸá¯ááŸááá±á¬áá±á¬á·áááºááá¯ážá
ááá¯ážááá¯ááºááẠááŒáá·áºáá±áá¬ážáá±á¬ á¡ááá®áá±ážááŸááºážáá
áºáá¯á meta áá±á¬ááºáá»á¬ážááᯠááŒáá·áºáá±áááºá¡ááœáẠáá±á¬ááºážááœááºáá±á¬ ááá¹ááá¬ážáá
áºáá¯ááŒá
áºáááºá configuration parameters ááœá±á áá¬ááœá±áá² áá²á· data ááœá±á áá¬áá²ááá¯áᬠáá¯á¶ážááŒááºááá¯á· ááá¯áá«áááºá áá¯ááºáá±á¬ááºáá»ááºáá
áºáá¯ááŸáááŒáá«á
áá¯á· C => A => B
ááŸáá·áº áá±á¬ááºáá»á¬áž C
áá±áá¬á¡ááŒá±á¬ááºážá¡áá²áááŸáááá±á¬ááºáá«á A
- áááŒá¬ááá áá®ááá
á¹á
ááŸá¬ áá»áœááºáá±á¬áºááá¯á· ááŒá±á¬ááá¯ááºáá«áááºá C
- configuration parameters áá»á¬ážááŸáá·áº A
- á¡áá»ááºá¡áááºá áá±áá°áá»á¡á¬ážááŒáá·áº áááºážááá¯á·ááẠáá±áá¬ááẠáááŒá¬áá ááŒá±á¬ááºážáá²áá±á·ááŸááá±á¬ááŒá±á¬áá·áº ááœá²á·á
ááºážááŸá¯áá±á¬ááºáá»á¬ážááẠáá±áá¬ááŸáá·áº ááœá²ááŒá¬ážááŒá±á¬ááºáž ááœá±á·ááŸáááá«áááºá ááá¯á·á¡ááŒááºá áá±áá¬áá»á¬ážááẠá¡áá»á¬ážá¡á¬ážááŒáá·áº á¡áááºážá¡ááŒá
áºáá
áºáᯠ(á¡áá¯á¶ážááŒá¯áá°ááŸ) ááŸáá·áº á¡ááŒá¬ážáá
áºáá¯á០á
á®á
ááºáááºááŸááºááŸá¯áá±á¬ááºáá»á¬áž (á
áá
áºá
á®áá¶ááá·áºááœá²áá°ááŸ) ááá¯á·ááŒá
áºáááºá
áááá¯ááááºááᯠááŒááºáááºá áááºááŒááºážáááŸááá² ááŒá±á¬ááºážáá²áá²áá±á¬ ááá·áºáááºáá±á¬ááºáá»á¬ážááᯠá¡ááºááááºáá¯ááºááẠááá¯á¡ááºáá«áá áááºážááẠáááá¯ááááºá ááŸá¯ááºááœá±ážááŸá¯ááᯠáááŒá¬áá ááŒá áºáá±á«áºá á±ááá¯ááºáááºá á¡ááŒá±á¬ááºážááŸá¬ áá»áœááºá¯ááºááá¯á·ááẠááá·áºáááºáá±á¬ááºáá»á¬ážááᯠáá áºáááºážáááºážááŒáá·áº áá±ážááá¯á·ááŒááºážá ááááºážáááºážááŒááºážá ááœá²ááŒááºážá áááºááŒá¬á á áºáá±ážááŒááºážááŸáá·áº ááŸá¬ážááœááºážáá±áá±á¬ áááºááá¯ážáá»á¬ážááᯠáá¯ááºáá±á¬ááºááẠááá¯á¡ááºáá±á¬ááŒá±á¬áá·áº ááŒá áºáááºá ááá¯á·ááŒá±á¬áá·áº áááá¯ááááºá ááŸá¯ááºááœá±ážááŸá¯ááᯠáá»áŸá±á¬á·áá»ááŒááºážá ááŸá¯áá±á¬áá·áºááŸááŒáá·áºáá»áŸáẠáááá¯ááááºáááºáááºááŸá¯á¡ááœááºáž ááŒá±á¬ááºážáá²ááá¯ááºáá±á¬ ááá·áºáááºáá»ááºáá»á¬áž á¡áá±á¡ááœááºááᯠáá»áŸá±á¬á·áá»ááẠ(ááá¯á·ááá¯áẠááá¯áá²á·ááá¯á·áá±á¬ ááá·áºáááºáá±á¬ááºáá»á¬ážááᯠáá¯á¶ážá ááá¶á·ááá¯ážáá«)á
á€ááá¯á·á áºááááºááœááºáá»ááºá¡ááœááºá áá»áœááºá¯ááºááá¯á·ááẠstatic ááŸáá·áº dynamic parameters áá»á¬ážá¡ááŒá¬áž ááœá²ááŒá¬ážááœá¬ážáá«áááºá á¡áááºá áááºáá±á¬ááºááŸá¯á áá¯áá¹áááá±áááẠáááá¯ááááºá áá¯ááºáá±á¬ááºááŸá¯á¡ááœááºáž áá±á¬ááºáá»á¬ážááᯠááŒá±á¬ááºážáá²ááẠááá¯á¡ááºáá«áá ááá¯áá²á·ááá¯á·áá±á¬ áá±á¬ááºáá»á¬ážááᯠááœá±á·áá»á¬ážáá±áááºáᯠáá»áœááºá¯ááºááá¯á·áá±á«áºááá¯áá«áááºá ááá¯ááºáá«á ááœá±ážáá»ááºá áá¬áá»á¬ážááẠáááºááŒáááºáá±ááŒá®áž á á¯á ááºážáá¬ážáá±á¬ ááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááᯠá¡áá¯á¶ážááŒá¯á ááŒááºáááºááá¯ááºáááºá ááŒá±á¬ááºážáá²áá±áá±á¬ ááŒááºáááºááœá²á·á ááºážááŸá¯á¡ááœááºá áááºáááºááŸá¯á áá Ạáá¯ááºáááºážá ááºáá»á¬ážááᯠááŒááºáááºá áááºáá¯á¶ááŸáá·áº áááºáá°áá±á¬ ááá·áºáááºáá»ááºá¡áá áºáá»á¬ážááŒáá·áº áááá¯ááááºá á¡á áááºá¡ááá¯ááºážáá»á¬ážááᯠááŒááºáááºá áááºááẠááá¹ááá¬ážáá áºáᯠááá¯á¡ááºáá«áááºá (áá»áœááºá¯ááºááá¯á·á á¡ááŒááºá¡áá áááºážááẠá áá áºá ááŸá¯ááºááœá±ážááŸá¯ááᯠááá¯ážááŒáá·áºáá¬áá±á¬ááŒá±á¬áá·áº á¡áá»áááºááŸáá·áºáááŒá±ážáá® ááŒááºáááºááœá²á·á ááºážááŒááºážááᯠááŸá±á¬ááºááŸá¬ážááẠá¡ááŒá¶ááŒá¯ááá¯áá«áááºá ááŒá áºááá¯ááºáá«áá áá¯ááºáááºážá ááºáá»á¬áž ááŒááºáááºá áááºáááºá¡ááœáẠá ᶠOS á áœááºážáááºáá»á¬ážááᯠá¡áá¯á¶ážááŒá¯ááŒááºážááẠááá¯áá±á¬ááºážáá«áááºá)
áá°ááœá±ááᯠdynamic reconfiguration ááá¯ááá·áºááœááºážá
ááºážá
á¬ážá
á±ááá·áº static configuration ááá¯á¡áá¯á¶ážááŒá¯ááŒááºážáá¡áá±ážááŒá®ážáá±á¬á¡áá»ááºáá
áºáá¯ááŸá¬ configuration update (downtime) ááŒá®ážáá±á¬áẠsystem ááá¯ááŒááºáááºá
áááºáááºá¡áá»áááºááŒá
áºáááºá á¡ááŸááºááŸá¬á áá»áœááºá¯ááºááá¯á·ááẠstatic configuration ááᯠááŒá¯ááŒááºááŒá±á¬ááºážáá²ááẠááá¯á¡ááºáá«áá áááºááá¯ážá¡áá
áºáá»á¬áž á¡áááºáááºá
á±ááẠá
áá
áºááᯠááŒááºáááºá
áááºááááºááŒá
áºáá«áááºá á
ááºáááºáá»áááºááŒá¿áá¬ááẠááá°áá®áá±á¬á
áá
áºáá»á¬ážá¡ááœáẠááŒááºážáááºááŸá¯ááœá²ááŒá¬ážáááºá á¡áá»áá¯á·ááá
á¹á
áá»á¬ážááœááºá áááºá¡áááºážáá¯á¶ážá¡áá»áááºá ááŒááºáááºá
áááºááẠá¡áá»áááºááá¬ážááœá²ááá¯ááºáááºá á
ááºáááºáááŒáẠáááºáá±á¬ááºááŸá¯áá±ážááẠááá¯á¡ááºáá«á á¡áá±á¬ááºá¡áááºáá±á¬áºááá¯ááºáá«áááºá
á¡áá±á¬ááºá¡áŠá¡ááœááºáž ááá¯á·ááá¯áẠá¡ááŒááºááœáẠááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááᯠááááºážáááºážááŒááºážááá¯ááºáᬠááŒá¿áá¬ááᯠááᯠá ááºážá á¬ážááŒáá·áºááŒáá«á áá¯á·á á¡áááºá áá»áœááºá¯ááºááá¯á·ááẠááŸá±ážáá±á¬ááºážáá á¹á ááºážáá áºáá¯á¡ááœááºáž ááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááᯠááááºážáááºážáá¬ážáá«áá ááá¯á·áá±á¬áẠá¡áááºážáá¯á¶áž ááŸá±ážáá±á¬ááºážáá á¹á ááºážá á¯áá±ážá ááºá¡ááœááºáž ááœá²á·á ááºážááŸá¯áá¯á¶á á¶áááŸááºáááºááŸá¯ááᯠáá»áœááºá¯ááºááá¯á·á¡áááºááŒá¯ááẠá¡ááœáá·áºá¡áá±ážááá²á·áááºá ááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááẠááááºážáá»á¯ááºáá¬ážáá±á¬ ááŸá±ážáá±á¬ááºážáá á¹á ááºážá¡ááŒááºáááºááœáẠááŸááá±áá«áá á€ááá¯ááºááᯠáááºáá°á á¡ááŒá±á¬ááºážá¡áá²ááŒá¯áá¯ááºáá²á·ááŒá±á¬ááºážááŸáá·áº á¡ááŒá±á¬ááºážáááºážááᯠááŒá±áá¬áá¶ááẠáááºáá²áááºá áááºáá±á¬ááºá¡áá±ážááŒá®ážáá² áá»áœááºá¯ááºááá¯á·áá¡ááŒááºá¡áá áá¯ááºáá¯ááºááŸá¯á áá áºáá»á¬ážá áœá¬á¡ááœáẠáááºááŒáááºááŒá®áž á¡áááºá¡ááœá±ážááŒáá·áº ááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááŸáááẠá¡áá±ážááŒá®ážáá«áááºá
ááŸá±ážáá±á¬ááºážáá á¹á ááºážááá¬ážááŸááºážááẠáááºážááá¯áááºáá®ážááá·áºá¡áá»áááºá áááºážááœáẠáááºááá·áºáááºááá¯ážáá»á¬ážáá«ááŸááááºá áááºááá·áºáá¯ááºáá±á¬ááºáá»ááºáá»á¬ážááᯠááœáá·áºáá¬ážáááº/ááááºáá¬ážáááºá ááŸáá·áº ááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááŒá±á¬ááºážáá²ááŸá¯áá»á¬ážá¡ááœáẠáááºáá°ááŸá¬ áá¬áááºááŸááááºááᯠáá¯á¶ážááŒááºáááºááœáá·áºááŒá¯áááºá áá¯ááºáá«áááºáá ááŸá±ážáá±á¬ááºážáá á¹á ááºážáá áºáá¯á¡ááœááºáž ááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááᯠááááºážáááºážáá¬ááœáẠá¡á¬ážáá¯ááºááŸá¯á¡áááºážááẠááá¯á¡ááºáááºá ááá¯á·ááŒá±á¬áá·áº áááºá¡ááá¥á¬ááºááŒáá·áº áá¯á¶ážááŒááºáá»ááºáá»ááẠááá¯á¡ááºáá«áááºá
Pro áá²á· con
á¡ááá¯ááŒá¯áá¬ážáá±á¬ áááºážááá¬á áá±á¬ááºážáá»áá¯áž ááá¯ážáá»áá¯ážáá»á¬ážá¡áá±á«áº ááŸá®ááá¯ááá¯áá«áááºá
á¡á¬ážáá¬áá»ááºáá»á¬áž
á¡á±á¬ááºááœáẠá á¯á ááºážáá¬ážáá±á¬ ááŒáá·áºáá±ááŸá¯á áá áºááœá²á·á ááºážáá¯á¶á á¡áááá¡ááºá¹áá«áááºáá»á¬ážá á¬áááºážááŒá áºáááº-
- Static configuration ááá¯á
á
áºáá±ážáá«á áá±áá»á¬ááá¯ááºááááºá
configuration ááŸááºáááºáá«áááºá - ááŒáœááºááá±á¬ááœá²á·á
ááºážááŸá¯áá¬áá¬á
áá¬ážá áá¯á¶ááŸááºá¡á¬ážááŒáá·áºá á¡ááŒá¬ážááœá²á·á
ááºážáá¯á¶áááºážáááºážáá»á¬ážááẠstring variable á¡á
á¬ážááá¯ážááŒááºážááᯠá¡áá»á¬ážáá¯á¶ážááá·áºáááºáá¬ážáááºá Scala ááá¯á¡áá¯á¶ážááŒá¯áá±á¬á¡áá«ááœááºá áááºáááœá²á·á
ááºážáá¯á¶ááᯠááá¯ááá¯áá±á¬ááºážááœááºá
á±áááºá¡ááœáẠáá»ááºááŒáá·áºáá±á¬áá¬áá¬á
áá¬ážá¡ááºá¹áá«áááºáá»á¬ážááᯠáááŸáááá¯ááºáááºá á¥ááᬠáá»áœááºáá±á¬áºááá¯á· áá¯á¶ážááá¯ááºáááºá
áá¯á¶áá±áááºááá¯ážáá»á¬ážá¡ááœáẠá ááá¯ááºááá¹ááá¬áá»á¬áž á¡á¯ááºá á¯ááá¯ááºááá·áºáááºáá±á¬ááºáá»á¬ážááá¯á· á¡áá¬ááá¹áá¯áá»á¬ážááá¯á¡áá¯á¶ážááŒá¯á ááá·áºáááºáá±á¬ááºá¡ááœááºáž áá áºááŒáááºáᬠ(DRY) ááŒá±ááŒá¬áá¬ážáá±á¬ vals áá»á¬ážááᯠááá¯ážáá¬ážááá¯ááºáá«áááºá configuration á¡ááœááºážááœáẠáááºááá·áºá¡áááºážááá¯áááᯠááẠáá»ááºáá»ááºáž áá¯ááºááá¯ááºááẠ(Seq
,Map
á áááºááŒáá¯ááºá¡áááºážáá»á¬áž)á - DSL Scala ááœáẠDSL ááá¯áááºáá®ážááẠááá¯ááá¯ááœááºáá°á á±ááá·áº áá¬áá¬á áá¬ážá¡ááºá¹áá«áááºáá»á¬ážá áœá¬ááŸááááºá á€á¡ááºá¹áá«áááºáá»á¬ážááᯠá¡ááœáá·áºáá±á¬ááºážáá°ááŒá®áž á¡áá¯á¶ážááŒá¯áá°áá»á¬ážá áá áºááŸááºá¡á¯ááºá á¯á¡ááœáẠááá¯ááá¯á¡áááºááŒá±ááá·áº ááœá²á·á ááºážááŸá¯áá¬áá¬á áá¬ážááᯠá¡áá±á¬ááºá¡áááºáá±á¬áºááẠááŒá áºááá¯ááºáááºá ááá¯á·ááŒá±á¬áá·áº ááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááᯠááá¯ááááºážáá»áœááºážáá»ááºáá°áá»á¬ážá á¡áááºážáá¯á¶ážáááºááŸá¯ááá¯ááºá á±áááºá á¥ááá¬á¡á¬ážááŒáá·áº áá»áœááºážáá»ááºáá°áá»á¬ážááẠá á®á ááºáááºááŸááºááŸá¯ ááŒááºáááºáá¯á¶ážáááºááŒááºážáá¯ááºáááºážá ááºááœáẠáá«áááºááá¯ááºáááºá
- node áá»á¬ážááŒá¬ážááœáẠááá¬ááááŸáá·áº áááºáá°áá»ááŸá¯á á¡áá»ááºáá áºáá¯áááºážááœáẠááááºážáááºážáá¬ážáá±á¬ ááŒáá·áºáá±ááŸá¯á áá áºáá áºáá¯áá¯á¶ážá ááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááŸáááŒááºážá á¡á¬ážáá¬áá»ááºáá áºáá¯ááŸá¬ áááºááá¯ážáá»á¬ážá¡á¬ážáá¯á¶ážááᯠáá áºááŒáááºááááááŒá±áá¬ááŒá®áž ááá¯á¡ááºááá·áºáá±áá¬ááá¯ááºážááœáẠááŒááºáááºá¡áá¯á¶ážááŒá¯ááŒááºážááŒá áºáááºá ports áá»á¬ážááá¯ááŒá±ááŒá¬ááẠphantom á¡áá»áá¯ážá¡á á¬ážáá»á¬ážááá¯á¡áá¯á¶ážááŒá¯ááŒááºážááŒáá·áº ááŸááºáááºáá±á¬á áá áºááœá²á·á ááºážáá¯á¶á¡á¬ážáá¯á¶ážááœáẠnode áá»á¬ážááẠááá¯ááºáááºáá®áá±á¬áááá¯ááá¯áá±á¬áá»á¬ážááá¯á¡áá¯á¶ážááŒá¯ááŒá±á¬ááºážáá±áá»á¬á á±áááºá node áá»á¬ážááŒá¬ážááœáẠááŒááºáá¬ážá áœá¬áááŒá áºááá±ááŸá®ááá¯áá±áááŒááºážááẠáááºáá±á¬ááºááŸá¯á¡á¬ážáá¯á¶ážááá¯áá»áááºáááºáá¬ážááŒá±á¬ááºáž áá±áá»á¬á á±áááºá
- á¡áááºá¡ááœá±ážááŒáá·áº á¡ááŒá±á¬ááºážá¡áá²áá»á¬ážá áá¯á¶ááœá¶á·ááŒáá¯ážááá¯ážáááºááŸá¯ áá¯ááºáááºážá ááºááᯠá¡áá¯á¶ážááŒá¯á ááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááᯠááŒá¯ááŒááºááŒá±á¬ááºážáá²ááŸá¯áá»á¬áž ááŒá¯áá¯ááºááŒááºážááŒáá·áº ááœá²á·á ááºážááŸá¯áá¯á¶á á¶á¡ááœáẠá¡áááºá¡ááœá±ážááŒáá·áºáá¬ážáá±á¬ á á¶ááŸá¯ááºážáá»á¬ážááᯠáááŸáá á±áááºááŒá áºáááºá
- áááŒáá¯ááºáááºáááºáž ááœá²á·á ááºážááŸá¯áá¯á¶á ᶠááœááºážáá¶ááŒááºážá ááœá²á·á ááºážááŸá¯á¡ááŒá±á¬ááºážá¡áá²áá»á¬ážááŒá®ážáá±á¬áẠá¡ááá¯á¡áá»á±á¬ááºá áá áºááŒáá·áºáá»ááºááŒááºážááẠnode á¡á¬ážáá¯á¶ážááᯠá¡ááºááááºáá¯ááºááŒá±á¬ááºáž áá±áá»á¬á á±áááºá
- áá»áŸá±á¬ááºááœáŸá¬ááá¯ááá¯ážááŸááºážá á±áááºá á¡ááá®áá±ážááŸááºážááẠááœá²ááŒááºážá áááºááŒá¬ááŒááºážá ááœá²á·á ááºážááŸá¯á á áºáá±ážááŒááºáž ááá¯á·ááá¯áẠááŸá¬ážááœááºážáá±áá±á¬áááºááá¯ážáá»á¬ážááᯠááá¯ááºááœááºááẠáááá¯á¡ááºáá«á áááºážááẠáá»áŸá±á¬ááºááœáŸá¬á ááŸá¯ááºááœá±ážááŸá¯ááᯠáá»á±á¬á·áááºážá á±áááºá (áá»áœááºá¯ááºááá¯á·áááá°áá¬ááœááºááœá±á·ááŸáááá±á¬ ááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááŸá¯ááºááœá±ážááŸá¯á¡áá»áá¯á·ááẠá á¯á ááºážááœá²á·á ááºážááŸá¯áá¯á¶á á¶á áááºááœáŸááºážáá»ááºááá¯ááºáá«á ááá¯ááá¯áá±á¬ááºážááœááºáá±á¬á¡áá»áá¯ážá¡á á¬ážáá±ážáááºážááŸá¯ááá¯áá±ážáá±á¬ááºááá¯áá±á¬ááá¹áááŒáá·áº áá±á¬ááºážááŸááºáá±á¬áááááŸááá±á¬áá¯á¶ážááŒááºáá»ááºáá áºáá¯áá¬ááŒá áºáááºá) áá¯á¶ááŸááºááœá²á·á ááºážáá¯á¶ááá¯á·ááŒááºááœá¬ážáááºá¡áá±á¬áºáá±ážááœááºáá°ááẠ- áá»á±á¬ááºáá¯á¶ážáá±áá±á¬á¡áá¬ááá¯á¡áá±á¬ááºá¡áááºáá±á¬áºáá¯á¶áá¬ááŒá áºáááºá á¡á áááºá¡ááá¯ááºážáá»á¬ážá ááá¯á·ááŒá±á¬áá·áºá á¥ááá¬á¡á¬ážááŒáá·áºá áááºááẠá¡ááŸááºáááẠááá¯á¡ááºááá·áºá¡áá»áááºá¡áá áááá¯á¡ááºáá±á¬ á¡á áááºá¡ááá¯ááºážáá»á¬áž á¡áá±á¬ááºá¡áááºáá±á¬áºááŸá¯ááᯠááŸá±á¬áá·áºááŸá±ážá á±áá±á¬ á á¯á ááºážááœá²á·á ááºážááŸá¯áá áºáá¯ááŒáá·áº á áááºááá¯ááºáááºá
- á¡áááºááŒá¯áá¬ážáá±á¬ ááœá²á·á ááºážááŸá¯áá¯á¶á á¶á ááœá²á·á ááºážááŸá¯ááŒá±á¬ááºážáá²ááŸá¯áá»á¬ážááẠá¡ááŒá¬ážááŒá±á¬ááºážáá²ááŸá¯áá»á¬ážá áá¬áá¬ááºáá¶ááŒáá¹áá¬ááᯠááá¯ááºáá¬áá±á¬ááŒá±á¬áá·áºá áá»áœááºá¯ááºááá¯á·áááŸáááá·áºááááºááẠáá°ážááŒá¬ážáá±á¬áá¬ážááŸááºážáá áºáá¯áá«ááŸááá±á¬ ááŸá±ážáá±á¬ááºážáá á¹á ááºážáá áºáá¯ááŒá áºáááºá áááºážááẠáá»áœááºá¯ááºááá¯á·á¡á¬áž ááá¯á¡ááºáá«áá á¥ááá¬á ááœá²á·á ááºážááŸá¯áá¯á¶á á¶á ááááºáá¬ážááŸááºážááá¯á· ááŒááºááœá¬ážááẠááœáá·áºááŒá¯áááºá áá»áœááºá¯ááºááá¯á·ááẠááœááºáá²á·ááá·áºáá áºááŸá áºááŸá áááºá ááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááá¯ááẠá¡áá¯á¶ážááŒá¯ááá¯ááºááŒá®áž á áá áºááẠá¡áá°áá°áááºá¡áá¯ááºáá¯ááºáááºááŒá áºáááºá áááºááŒáááºáá±á¬ááœá²á·á ááºážáá¯á¶ááẠááŒáá·áºáá±ááŸá¯á áá áºáá áºáá¯á ááŒáá¯áááºááá·áºááŸááºážááá¯ááºááŸá¯ááŸáá·áº áá¯á¶ááŒááºá áááºáá»áááŸá¯ááᯠááá¯ážáááºá á±áááºá configuration ááᯠcompilation á¡ááá·áºááœáẠááŒááºáááºáá¬ážáá±á¬ááŒá±á¬áá·áº áá¯ááºáá¯ááºáá±ážááœáẠáááºážááᯠá¡áá¯áá¯ááºááẠá¡ááœááºáááºáá²áá«áááºá
- ááœá±á·áá»á¬ážááŸá¯á á¡ááá¯ááŒá¯áá¬ážáá±á¬áá±á¬ááºááẠáá±á¬áºáá»á°áá¬ááŒá áºááŒá®áž ááœá²ááŒá¬ážáá±á¬á áá áºáá»á¬ážááᯠáááºáá®ážáááºá¡ááœáẠáá±á¬áºáá»á°ážáá»á¬ážááᯠááá°áá®áá±á¬áááºážáááºážáá»á¬ážááŒáá·áº áá±á«ááºážá ááºááá¯ááºáááºá á¡áá°ážáááŒáá·áºá embodiment áá áºáá¯ááŸá node áá áºáá¯ááœáẠá¡áá¯ááºáá¯ááºáááºááŸáá·áº á¡ááŒá¬áž node á¡áá»á¬ážá¡ááŒá¬ážááœáẠrun ááẠsystem ááᯠconfigure áá¯ááºááá¯ááºáá«áááºá á áá áºá áá¯ááºáá¯ááºááŸá¯ áá¬áááá»á¬áž á¡ááœáẠáá¯á¶á á¶á¡áá»á¬ážá¡ááŒá¬ážááᯠááẠáááºáá®ážááá¯ááºáááºá
- á ááºážáááºááŒááºážá áááºáá±á¬ááºááŸá¯áá áºáá¯áá»ááºážá á®ááᯠáá¯á¶ááá¹áá¬ááºá¡áá¬ááá¹áá¯áá»á¬ážááŒáá·áº á¡á á¬ážááá¯ážááŒááºážááŒáá·áºá á ááºážáááºáááºá¡ááœáẠá¡áááºááŒá±ááá·áº á áá áºáá¬ážááŸááºážáá»á¬ážá áœá¬ááᯠáááºáááá¯ááºáááºá
- áá±á«ááºážá ááºá ááºážáááºááŒááºážá ááŒáá·áºáá±ááŸá¯á áá áºáá áºáá¯áá¯á¶ážá¡ááœáẠáá áºáá¯áááºážáá±á¬ configuration áá áºáá¯ááŸáááŒááºážááẠáá±á«ááºážá ááºá ááºážáááºááŒááºážááá áºá áááºáá áºááá¯ááºážá¡ááŒá Ạááááºážáá»á¯ááºáá¬ážáá±á¬áááºáááºážáá»ááºááœáẠá¡á áááºá¡ááá¯ááºážá¡á¬ážáá¯á¶ážááᯠáá¯ááºáá±á¬ááºááá¯ááºá á±áááºá á¥ááá¬á¡á¬ážááŒáá·áºá á¡áá»áá¯á·áá±á¬ node áá»á¬ážááᯠá¡áá¯á¶ážááŒá¯ááááá¯ááºáá±á¬ á¡ááŒá±á¡áá±áá áºáá¯ááᯠá¡áá¯áá°ááẠááœááºáá°áááºá
á¡á¬ážáááºážáá»ááºáá»á¬ážááŸáá·áº ááá·áºáááºáá»ááºáá»á¬áž
á á¯á ááºážáá¬ážáá±á¬ ááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááẠá¡ááŒá¬ážááœá²á·á ááºážáá¯á¶áááºážáááºážáá»á¬ážááŸáá·áº ááœá²ááŒá¬ážááŒá®áž á¡áá»áá¯á·áá±á¬á¡ááºááºáá®áá±ážááŸááºážáá»á¬ážá¡ááœáẠááá·áºáá»á±á¬áºáááºááá¯ááºáá±á á¡á±á¬ááºáá±á¬áºááŒáá« á¡á¬ážáááºážáá»ááºáá»á¬áž
- Static configuration áá áºáá«áá áºáá¶ááœáẠáááºááẠá¡áá¬á¡ááœááºááá¹ááá¬ážá¡á¬ážáá¯á¶ážááᯠáá»á±á¬áºááŒááºáᬠáá¯ááºáá¯ááºááŸá¯ááœáẠááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááᯠá¡ááŒááºááŒááºááẠááá¯á¡ááºáááºá áá®áááºážáááºážáá²á·ááᯠááá¯áááºáá²ááá¯ááºáá«áááºá á¡áááºážáá¯á¶ážáá±á¬á· á á¯á ááºážááŸá¯ááŸáá·áº á¡ááá¯á¡áá»á±á¬áẠááŒáá·áºáá»ááºááŸá¯ ááá¯á¡ááºáá±áá±ážáááºá áááºážááẠáá»ááºážáááºááŸá¯á á¡áá¯á¶ážáááºáá±á¬á¡ááºá¹áá«áááºáá áºáá¯ááŒá áºááŒá®áž á¡áá»áá¯á·ááá á¹á áá»á¬ážááœáẠá¡á¬ážáááºážáá»ááºáá áºáá¯ááŒá áºáááºá
- ááœá²á·á ááºážááŸá¯áá»áá¯ážáááºá configuration ááá¯ááºááᯠá¡ááá¯á¡áá»á±á¬ááºáá°ážááºááŒáá·áº áá¯ááºáá¯ááºáá«á build script ááᯠáá±á«ááºážá ááºážááẠáá±á¬ááºááẠá¡á¬ážáá¯ááºááŸá¯áá»á¬áž ááá¯á¡ááºááá¯ááºáá«áááºá
- áááááá¬áá»á¬ážá áááºááŸáááœááºá configuration ááŒáá·áºá¡áá¯ááºáá¯ááºááẠáá®ááá¯ááºážáá¯ááºáá¬ážáá±á¬ utilities ááŸáá·áº techniques áá»á¬ážááẠtext files áá»á¬ážáá±á«áºááœáẠá¡ááŒá±áá¶áá¬ážáá«áááºá ááá¯ááá¯á·áá±á¬ á¡áá¯á¶ážá¡áá±á¬ááºáá»á¬áž/áááºážááá¬áá»á¬ážá¡á¬ážáá¯á¶ážááᯠá á¯á ááºážááœá²á·á ááºážááŸá¯ááœáẠáááá¯ááºáááºááá¯ááºáá±á
- ááá±á¬áá¬ážáá»á¬áž ááŒá±á¬ááºážáá²ááẠááá¯á¡ááºáááºá Developers ááŸáá·áº DevOps ááá¯á·ááẠá á¬áá¬ážááá¯ááºáá»á¬ážááᯠáá»áá·áºáá¬ážáááŒáááºá ááœá²á·á ááºážááŸá¯áá¯á¶á á¶áá áºáá¯ááᯠááŒá¯á á¯ááŒááºážá á áááºáá°ážááẠá¡áááºážáááºáá»áŸááá»áŸá±á¬áºááá·áºáá² áá°ážáá°ážááŒá¬ážááŒá¬áž ááŒá áºááá¯ááºááŒá®áž ááŒááºážáááºááŒááºážááᯠááŒá áºá á±áááºá
- á¡áááºá¡ááœá±ážááŒáá·áº ááœá¶á·ááŒáá¯ážááá¯ážáááºáá±áž áá¯ááºáááºážá ááºáá»á¬áž ááá¯á¡ááºáá«áááºá compiled configuration ááᯠá¡áááºááŒá±ááŒá± á¡áá¯á¶ážááŒá¯ááá¯ááºáááºá á¡ááá®áá±ážááŸááºáž áááºáá±á¬ááºááŒááºážááŸáá·áº á¡áá¯á¶ážáá»ááŒááºáž áá¯ááºáááºážá áẠ(CI/CD) á á¡ááŒáá·áºá¡á á¡ááá¯á¡áá»á±á¬ááºá áá Ạááá¯á¡ááºáá«áááºá ááá¯ááºááẠáá±á¬áºáá±á¬áº á¡áááºáááŒá±ááŒá áºáááá·áºáááºá
á á¯á ááºážáá¬ážáá±á¬ ááœá²á·á ááºážááŸá¯áá¯á¶á á¶á á¡áá°á¡áááŸáá·áº ááááºááá¯ááºáá±á¬ ááá·áºááœááºážá ááºážá á¬ážáá¬ážáá±á¬ á¥ááá¬á ááá·áºáááºáá»ááºáá»á¬ážá áœá¬ááá¯áááºáž áá»áœááºá¯ááºááá¯á·á¡á¬áž ááá¯ážáá¬ážááŒáá·áºááŒáá«á áá¯á·á
- á¡áááºá áá»áœááºá¯ááºááá¯á·ááẠnode ááŸá¡áá¯á¶ážáááŒá¯áá±á¬ áááá¯á¡ááºáá±á¬ configuration á¡áá»ááºá¡áááºáá»á¬ážááᯠáá±ážáá±á¬ááºáá«áá compiler ááẠáá»á±á¬ááºáá¯á¶ážáá±áá±á¬á¡áá±á¬ááºá¡áááºáá±á¬áºááŸá¯ááᯠááŸá¬ááœá±ááœá±á·ááŸáááẠáá»áœááºá¯ááºááá¯á·á¡á¬áž áá°áá®áááá·áºáááºááá¯ááºáá«á Cake Pattern ááᯠá
áœáá·áºááœáŸááºááŒá®áž ááá¯ááá¯áá±á¬áá·áºáááºážáá±á¬ á¡áá»áá¯ážá¡á
á¬ážáá»á¬ážááᯠá¡áá¯á¶ážááŒá¯ááŒááºážááŒáá·áº á€ááŒá¿áá¬ááᯠááŒá±ááŸááºážááá¯ááºáá«áááºá
HList
ááá¯á·ááá¯áẠá¡áá¹ááá¬áááºá¹áá»á¬ áá±áá¬á¡áá»áá¯ážá¡á á¬ážáá»á¬áž (ááŒá áºáááºááŸáẠá¡áááºážáá»á¬áž) ááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááᯠááá¯ááºá á¬ážááŒá¯áááºá - configuration ááá¯ááºááá¯ááºááŸáá·áºááááºááá¯ááºáá±á¬ configuration file ááœáẠááá¯ááºážáá»á¬ážááŸááá«áááºá
package
,import
ááŒá±ááŒá¬áá»ááºáá»á¬ážáoverride def
áá¯á¶áá±áááºááá¯ážáá»á¬ážááŸááá±á¬ áá±á¬ááºáá»á¬ážá¡ááœáẠ's)á ááá·áºááá¯ááºááá¯áẠDSL ááᯠá¡áá¯á¶ážááŒá¯áá«á áááºážááᯠáá áºá áááºáá áºááá¯ááºáž ááŸá±á¬ááºááŸá¬ážááá¯ááºáááºá ááá¯á·á¡ááŒááºá á¡ááŒá¬ážááœá²á·á ááºážáá¯á¶á¡áá»áá¯ážá¡á á¬ážáá»á¬áž (á¥ááá¬á XML) áááºáááºáž ááá¯ááºááœá²á·á ááºážáá¯á¶á¡áá±á«áº ááá·áºáááºáá»ááºáá»á¬ážá¡áá»áá¯á·ááᯠáá»ááŸááºáá¬ážáááºá - á€ááá¯á·á áºááááºááœááºáá»ááºá¡ááœááºá áá»áœááºá¯ááºááá¯á·ááẠá¡áá¬ážáá° node á¡á á¯á¡áá±ážáá áºáá¯á ááœá±á·áá»á¬ážááŒá±á¬ááºážáá²ááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááᯠááá·áºááœááºážá ááºážá á¬ážáááºááá¯ááºáá«á
áá±á¬ááºáá»ááº
á€ááá¯á·á áºááœááºá áá»áœááºá¯ááºááá¯á·ááẠScala á¡áá»áá¯ážá¡á á¬ážá áá áºáá¡ááá·áºááŒáá·áºáá±á¬á áœááºážáááºáá»á¬ážááᯠá¡áá¯á¶ážááŒá¯á á¡áááºážá¡ááŒá áºáá¯ááºááœááºááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááᯠááá¯ááºá á¬ážááŒá¯ááá·áºá áááºáá°ážááᯠáá±á·áá¬áá²á·áááºá xml ááá¯á·ááá¯áẠá á¬áá¬ážááá¯ááºáá»á¬ážááᯠá¡ááŒá±áá¶á ááá¯ážáá¬ááœá²á·á ááºážááŸá¯áááºážáááºážáá»á¬ážááᯠá¡á á¬ážááá¯ážáááºá¡ááœáẠá€áááºážáááºážááᯠá¡ááá®áá±ážááŸááºážá¡áá»áá¯ážáá»áá¯ážááœáẠá¡áá¯á¶ážááŒá¯ááá¯ááºáááºá áá»áœááºá¯ááºááá¯á·áááá°áá¬ááᯠScala ááœáẠá¡áá±á¬ááºá¡áááºáá±á¬áºáá±á¬áºáááºáž áá°áá®áá±á¬á áááºáá°ážáá»á¬ážááᯠá¡ááŒá¬ážá á¯á ááºážáá¬ážáá±á¬áá¬áá¬á áá¬ážáá»á¬áž (á¥ááᬠKotliná C#á Swiftá ...) ááá¯á· ááœáŸá²ááŒá±á¬ááºážááá¯ááºáá«áááºá á¡á±á¬ááºáá«ááá±á¬áá»ááºáá»á¬ážáá²á០áá áºáá¯ááœáẠá€áá»ááºážáááºáááºážááᯠáááºá ááºážááŒáá·áºááá¯ááºááŒá®ážá áááºážááẠá¡áá¯ááºááá¯ááºáá«á á á¬áá¬ážááá¯ááºááá¯á· ááœáŸá±á·áᬠáá»á±á¬ááºáá¯á¶ážáá±áá±á¬ á¡á áááºá¡ááá¯ááºážáá»á¬ážááᯠáá±á«ááºážááá·áºáá«á
ááá¬áá¡á¬ážááŒáá·áºá á á¯á ááºážááœá²á·á ááºážááŸá¯áá áºáá¯ááẠá¡áááºá¡ááœá±ážááŒáá·áº ááœá¶á·ááŒáá¯ážááá¯ážáááºááŸá¯áá¯ááºáááºážá ááºáá áºáᯠááá¯á¡ááºáá«áááºá á¡ááŒááºá¡ááŸááºá¡á¬ážááŒáá·áºá ááœá²á·á ááºážááŸá¯áá¯á¶á á¶áá»á¬ážá á¡áááºá¡ááœá±ážááŸáá·áº áá¯á¶ááŒááºá áááºáá»áááŸá¯ááᯠá¡á¬ááá¶áá«áááºá
ááá·áºááœááºážá ááºážá á¬ážáá±á¬áá»ááºážáááºááŸá¯ááᯠáá»á²á·ááœááºááá¯ááºáááºá
- compile-time checks áá¯ááºááẠmacro ááá¯áá¯á¶ážááá¯ááºáááºá
- á¡áá¯á¶ážááŒá¯áá°áá»á¬ážáááºááŸááºážáá®ááá¯ááºáá±á¬áá¯á¶á á¶ááŒáá·áº configuration ááá¯áááºááŒááẠDSL ááá¯áááºá¡áá±á¬ááºá¡áááºáá±á¬áºááá¯ááºáááºá
- á¡ááá¯á¡áá»á±á¬ááºááœá²á·á ááºážáá¯á¶ áá»áááºááŸáááŸá¯ááŒáá·áº ááŒá±á¬ááºážáá²áá±áá±á¬ á¡áááºážá¡ááŒá áºá á®áá¶ááá·áºááœá²ááŸá¯ááᯠááẠá¡áá±á¬ááºá¡áááºáá±á¬áºááá¯ááºáááºá á¥ááá¬á¡á¬ážááŒáá·áºá á¡á á¯á¡áá±ážáá áºáá¯ááŸá node á¡áá±á¡ááœááºááá¯ááŒá±á¬ááºážáá²ááŒááºáž (1) node áá áºáá¯á á®ááẠá¡áááºážáááºááœá²ááŒá¬ážáá±á¬ááœá²á·á ááºážááŸá¯áá áºáá¯ááᯠáááºáá¶áááŸááááºááá¯á¡ááºáá«áááºá (2) á¡á á¯á¡áá±ážáááºáá±áá»á¬ááẠnode á¡áá áºáá»á¬ážááá¯ááºáᬠá¡áá»ááºá¡áááºáá»á¬ážááᯠáááºáá¶áááŸááá²á·áááºá
áá»á±ážáá°ážáááºááœáŸá¬
Andrei Saksonová Pavel Popov ááŸáá·áº Anton Nekhaev ááá¯á·ááẠáá±á¬ááºážáá«ážáá°ááŒááºážá¡ááœáẠá¡ááŒá¯ááá±á¬áá±á¬ááºáá±á¬ áá±áááºááŸá¯áá»á¬ážá¡ááœáẠáá»á±ážáá°ážáááºááá¯áá«áááºá
source: www.habr.com