ืชืฆื•ืจืช ืžืขืจื›ืช ืžื‘ื•ื–ืจืช ืžื”ื•ื“ืจืช

ืื ื™ ืจื•ืฆื” ืœืกืคืจ ืœื›ื ืžื ื’ื ื•ืŸ ืžืขื ื™ื™ืŸ ืื—ื“ ืœืขื‘ื•ื“ื” ืขื ืชืฆื•ืจื” ืฉืœ ืžืขืจื›ืช ืžื‘ื•ื–ืจืช. ื”ืชืฆื•ืจื” ืžื™ื•ืฆื’ืช ื™ืฉื™ืจื•ืช ื‘ืฉืคื” ืžื”ื•ื“ืจืช (Scala) ื‘ืืžืฆืขื•ืช ืกื•ื’ื™ื ื‘ื˜ื•ื—ื™ื. ืคื•ืกื˜ ื–ื” ืžืกืคืง ื“ื•ื’ืžื” ืœืชืฆื•ืจื” ื›ื–ื• ื•ื“ืŸ ื‘ื”ื™ื‘ื˜ื™ื ืฉื•ื ื™ื ืฉืœ ื™ื™ืฉื•ื ืชืฆื•ืจื” ืžื”ื•ื“ืจืช ื‘ืชื”ืœื™ืš ื”ืคื™ืชื•ื— ื”ื›ื•ืœืœ.

ืชืฆื•ืจืช ืžืขืจื›ืช ืžื‘ื•ื–ืจืช ืžื”ื•ื“ืจืช

(ืื ื’ืœื™ืช)

ืžื‘ื•ื

ื‘ื ื™ื™ืช ืžืขืจื›ืช ืžื‘ื•ื–ืจืช ืืžื™ื ื” ืคื™ืจื•ืฉื” ืฉื›ืœ ื”ืฆืžืชื™ื ืžืฉืชืžืฉื™ื ื‘ืชืฆื•ืจื” ื”ื ื›ื•ื ื”, ื”ืžืกื•ื ื›ืจื ืช ืขื ืฆืžืชื™ื ืื—ืจื™ื. ื˜ื›ื ื•ืœื•ื’ื™ื•ืช DevOps (terraform, ansible ืื• ืžืฉื”ื• ื›ื–ื”) ืžืฉืžืฉื•ืช ื‘ื“ืจืš ื›ืœืœ ืœื™ืฆื™ืจืช ืงื‘ืฆื™ ืชืฆื•ืจื” ืื•ื˜ื•ืžื˜ื™ืช (ืœืขื™ืชื™ื ืงืจื•ื‘ื•ืช ืกืคืฆื™ืคื™ื™ื ืœื›ืœ ืฆื•ืžืช). ืื ื• ื’ื ืจื•ืฆื™ื ืœื”ื™ื•ืช ื‘ื˜ื•ื—ื™ื ืฉื›ืœ ื”ืฆืžืชื™ื ื”ืžืชืงืฉืจื™ื ืžืฉืชืžืฉื™ื ื‘ืคืจื•ื˜ื•ืงื•ืœื™ื ื–ื”ื™ื (ื›ื•ืœืœ ืื•ืชื” ื’ืจืกื”). ืื—ืจืช, ืื™ ืชืื™ืžื•ืช ืชื”ื™ื” ืžื•ื‘ื ื™ืช ื‘ืžืขืจื›ืช ื”ืžื‘ื•ื–ืจืช ืฉืœื ื•. ื‘ืขื•ืœื JVM, ืื—ืช ื”ื”ืฉืœื›ื•ืช ืฉืœ ื“ืจื™ืฉื” ื–ื• ื”ื™ื ืฉื™ืฉ ืœื”ืฉืชืžืฉ ื‘ืื•ืชื” ื’ืจืกื” ืฉืœ ื”ืกืคืจื™ื™ื” ื”ืžื›ื™ืœื” ืืช ื”ื•ื“ืขื•ืช ื”ืคืจื•ื˜ื•ืงื•ืœ ื‘ื›ืœ ืžืงื•ื.

ืžื” ืœื’ื‘ื™ ื‘ื“ื™ืงืช ืžืขืจื›ืช ืžื‘ื•ื–ืจืช? ื›ืžื•ื‘ืŸ, ืื ื• ืžื ื™ื—ื™ื ืฉืœื›ืœ ื”ืจื›ื™ื‘ื™ื ื™ืฉ ื‘ื“ื™ืงื•ืช ื™ื—ื™ื“ื” ืœืคื ื™ ืฉืื ื• ืขื•ื‘ืจื™ื ืœื‘ื“ื™ืงื•ืช ืื™ื ื˜ื’ืจืฆื™ื”. (ื›ื“ื™ ืฉื ื•ื›ืœ ืœื‘ืฆืข ืืงืกื˜ืจืคื•ืœืฆื™ื” ืฉืœ ืชื•ืฆืื•ืช ื‘ื“ื™ืงื” ืœื–ืžืŸ ืจื™ืฆื”, ืขืœื™ื ื• ืœืกืคืง ื’ื ืงื‘ื•ืฆื” ื–ื”ื” ืฉืœ ืกืคืจื™ื•ืช ื‘ืฉืœื‘ ื”ื‘ื“ื™ืงื” ื•ื‘ื–ืžืŸ ื”ืจื™ืฆื”.)

ื›ืฉืขื•ื‘ื“ื™ื ืขื ืžื‘ื—ื ื™ ืื™ื ื˜ื’ืจืฆื™ื”, ืœืจื•ื‘ ืงืœ ื™ื•ืชืจ ืœื”ืฉืชืžืฉ ื‘ืื•ืชื• ื ืชื™ื‘ ืžื—ืœืงื” ื‘ื›ืœ ืžืงื•ื ื‘ื›ืœ ื”ืฆืžืชื™ื. ื›ืœ ืฉืขืœื™ื ื• ืœืขืฉื•ืช ื”ื•ื ืœื•ื•ื“ื ืฉืžืฉืชืžืฉื™ื ื‘ืื•ืชื• ื ืชื™ื‘ ืžื—ืœืงื” ื‘ื–ืžืŸ ืจื™ืฆื”. (ืืžื ื ื–ื” ืืคืฉืจื™ ืœื—ืœื•ื˜ื™ืŸ ืœื”ืคืขื™ืœ ืฆืžืชื™ื ืฉื•ื ื™ื ืขื ื ืชื™ื‘ื™ื ืฉื•ื ื™ื, ืื‘ืœ ื–ื” ืžื•ืกื™ืฃ ืžื•ืจื›ื‘ื•ืช ืœืชืฆื•ืจื” ื”ื›ื•ืœืœืช ื•ืœืงืฉื™ื™ื ืขื ื‘ื“ื™ืงื•ืช ืคืจื™ืกื” ื•ืื™ื ื˜ื’ืจืฆื™ื”.) ืœืžื˜ืจื•ืช ืคื•ืกื˜ ื–ื”, ืื ื• ืžื ื™ื—ื™ื ืฉื›ืœ ื”ืฆืžืชื™ื ื™ืฉืชืžืฉื• ื‘ืื•ืชื• classpath.

ื”ืชืฆื•ืจื” ืžืชืคืชื—ืช ืขื ื”ืืคืœื™ืงืฆื™ื”. ืื ื• ืžืฉืชืžืฉื™ื ื‘ื’ืจืกืื•ืช ื›ื“ื™ ืœื–ื”ื•ืช ืฉืœื‘ื™ื ืฉื•ื ื™ื ืฉืœ ื”ืชืคืชื—ื•ืช ื”ืชื•ื›ื ื™ืช. ื ืจืื” ื”ื’ื™ื•ื ื™ ืœื–ื”ื•ืช ื’ื ื’ืจืกืื•ืช ืฉื•ื ื•ืช ืฉืœ ืชืฆื•ืจื•ืช. ื•ื”ืฆื‘ ืืช ื”ืชืฆื•ืจื” ืขืฆืžื” ื‘ืžืขืจื›ืช ื‘ืงืจืช ื”ื’ืจืกืื•ืช. ืื ื™ืฉ ืจืง ืชืฆื•ืจื” ืื—ืช ื‘ื™ื™ืฆื•ืจ, ืื– ืื ื—ื ื• ื™ื›ื•ืœื™ื ืคืฉื•ื˜ ืœื”ืฉืชืžืฉ ื‘ืžืกืคืจ ื”ื’ืจืกื”. ืื ื ืฉืชืžืฉ ื‘ืžื•ืคืขื™ ื™ื™ืฆื•ืจ ืจื‘ื™ื, ืื– ื ืฆื˜ืจืš ื›ืžื”
ืขื ืคื™ ืชืฆื•ืจื” ื•ืชื•ื•ื™ืช ื ื•ืกืคืช ื‘ื ื•ืกืฃ ืœื’ืจืกื” (ืœื“ื•ื’ืžื”, ืฉื ื”ืกื ื™ืฃ). ื›ืš ื ื•ื›ืœ ืœื–ื”ื•ืช ื‘ื‘ื™ืจื•ืจ ืืช ื”ืชืฆื•ืจื” ื”ืžื“ื•ื™ืงืช. ื›ืœ ืžื–ื”ื” ืชืฆื•ืจื” ืžืชืื™ื ื‘ืื•ืคืŸ ื™ื™ื—ื•ื“ื™ ืœืฉื™ืœื•ื‘ ืกืคืฆื™ืคื™ ืฉืœ ืฆืžืชื™ื ืžื‘ื•ื–ืจื™ื, ื™ืฆื™ืื•ืช, ืžืฉืื‘ื™ื ื—ื™ืฆื•ื ื™ื™ื ื•ื’ืจืกืื•ืช ืกืคืจื™ื™ื”. ืœืฆื•ืจืš ืคื•ืกื˜ ื–ื” ื ื ื™ื— ืฉื™ืฉ ืจืง ืขื ืฃ ืื—ื“ ื•ื ื•ื›ืœ ืœื–ื”ื•ืช ืืช ื”ืชืฆื•ืจื” ื‘ื“ืจืš ื”ืจื’ื™ืœื” ื‘ืืžืฆืขื•ืช ืฉืœื•ืฉื” ืžืกืคืจื™ื ืžื•ืคืจื“ื™ื ื‘ื ืงื•ื“ื” (1.2.3).

ื‘ืกื‘ื™ื‘ื•ืช ืžื•ื“ืจื ื™ื•ืช, ืœืขืชื™ื ื ื“ื™ืจื•ืช ื ื•ืฆืจื™ื ืงื‘ืฆื™ ืชืฆื•ืจื” ื‘ืื•ืคืŸ ื™ื“ื ื™. ืœืขืชื™ื ืงืจื•ื‘ื•ืช ื™ื•ืชืจ ื”ื ื ื•ืฆืจื™ื ื‘ืžื”ืœืš ื”ืคืจื™ืกื” ื•ืื™ื ื ื ื•ื’ืขื™ื ื‘ื”ื ืขื•ื“ (ื›ืš ืœื ืœืฉื‘ื•ืจ ื›ืœื•ื). ืžืชืขื•ืจืจืช ืฉืืœื” ื˜ื‘ืขื™ืช: ืžื“ื•ืข ืื ื• ืขื“ื™ื™ืŸ ืžืฉืชืžืฉื™ื ื‘ืคื•ืจืžื˜ ื˜ืงืกื˜ ืœืื—ืกื•ืŸ ืชืฆื•ืจื”? ื ืจืื” ื›ื™ ื—ืœื•ืคื” ืžืขืฉื™ืช ื”ื™ื ื”ื™ื›ื•ืœืช ืœื”ืฉืชืžืฉ ื‘ืงื•ื“ ืจื’ื™ืœ ืœืชืฆื•ืจื” ื•ืœื”ืคื™ืง ืชื•ืขืœืช ืžื‘ื“ื™ืงื•ืช ื‘ื–ืžืŸ ื”ื™ื“ื•ืจ.

ื‘ืคื•ืกื˜ ื–ื” ื ื—ืงื•ืจ ืืช ื”ืจืขื™ื•ืŸ ืฉืœ ื™ื™ืฆื•ื’ ืชืฆื•ืจื” ื‘ืชื•ืš ื—ืคืฅ ืžืœื•ืงื˜.

ืชืฆื•ืจื” ืžื•ืจื›ื‘ืช

ืกืขื™ืฃ ื–ื” ืžืกืคืง ื“ื•ื’ืžื” ืœืชืฆื•ืจืช ืงื•ืžืคื™ืœืฆื™ื” ืกื˜ื˜ื™ืช. ืฉื ื™ ืฉื™ืจื•ืชื™ื ืคืฉื•ื˜ื™ื ืžื™ื•ืฉืžื™ื - ืฉื™ืจื•ืช ื”ื“ ื•ืœืงื•ื— ืฉื™ืจื•ืช ื”ื“. ื‘ื”ืชื‘ืกืก ืขืœ ืฉื ื™ ืฉื™ืจื•ืชื™ื ืืœื”, ืžื•ืจื›ื‘ื•ืช ืฉืชื™ ืืคืฉืจื•ื™ื•ืช ืžืขืจื›ืช. ื‘ืื•ืคืฆื™ื” ืื—ืช ืฉื ื™ ื”ืฉื™ืจื•ืชื™ื ืžืžื•ืงืžื™ื ื‘ืื•ืชื• ืฆื•ืžืช, ื‘ืื•ืคืฆื™ื” ืื—ืจืช - ื‘ืฆืžืชื™ื ืฉื•ื ื™ื.

ื‘ื“ืจืš ื›ืœืœ ืžืขืจื›ืช ืžื‘ื•ื–ืจืช ืžื›ื™ืœื” ืžืกืคืจ ืฆืžืชื™ื. ืืชื” ื™ื›ื•ืœ ืœื–ื”ื•ืช ืฆืžืชื™ื ื‘ืืžืฆืขื•ืช ืขืจื›ื™ื ืžืกื•ื’ ื›ืœืฉื”ื• 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

ืฆืžืชื™ื ืžื‘ืฆืขื™ื ืชืคืงื™ื“ื™ื ืฉื•ื ื™ื, ื”ื ืžืคืขื™ืœื™ื ืฉื™ืจื•ืชื™ื ื•ื ื™ืชืŸ ืœื™ืฆื•ืจ ื‘ื™ื ื™ื”ื ื—ื™ื‘ื•ืจื™ TCP/HTTP.

ื›ื“ื™ ืœืชืืจ ื—ื™ื‘ื•ืจ TCP ืื ื—ื ื• ืฆืจื™ื›ื™ื ืœืคื—ื•ืช ืžืกืคืจ ื™ืฆื™ืื”. ื‘ืจืฆื•ื ื ื• ื’ื ืœืฉืงืฃ ืืช ื”ืคืจื•ื˜ื•ืงื•ืœ ื”ื ืชืžืš ื‘ื™ืฆื™ืื” ื–ื• ื›ื“ื™ ืœื”ื‘ื˜ื™ื— ืฉื’ื ื”ืœืงื•ื— ื•ื’ื ื”ืฉืจืช ืžืฉืชืžืฉื™ื ื‘ืื•ืชื• ืคืจื•ื˜ื•ืงื•ืœ. ื ืชืืจ ืืช ื”ืงืฉืจ ื‘ืืžืฆืขื•ืช ื”ืžื—ืœืงื” ื”ื‘ืื”:

case class TcpEndPoint[Protocol](node: NodeId, port: Port[Protocol])

ืื™ืคื” Port - ืจืง ืžืกืคืจ ืฉืœื Int ืžืฆื™ื™ืŸ ืืช ื˜ื•ื•ื— ื”ืขืจื›ื™ื ื”ืžืงื•ื‘ืœื™ื:

type PortNumber = Refined[Int, Closed[_0, W.`65535`.T]]

ื˜ื™ืคื•ืกื™ื ืžืขื•ื“ื ื™ื

ืจืื” ืกืคืจื™ื™ื” ืžืขื•ื“ืŸ ะธ ืฉืœื™ ืœื”ื’ื™ืฉ ืชืœื•ื ื”. ื‘ืงื™ืฆื•ืจ, ื”ืกืคืจื™ื™ื” ืžืืคืฉืจืช ืœื”ื•ืกื™ืฃ ืื™ืœื•ืฆื™ื ืœืกื•ื’ื™ื ืฉื ื‘ื“ืงื™ื ื‘ื–ืžืŸ ื”ื”ื™ื“ื•ืจ. ื‘ืžืงืจื” ื–ื”, ืขืจื›ื™ ืžืกืคืจ ื™ืฆื™ืื” ื—ื•ืงื™ื™ื ื”ื ืžืกืคืจื™ื ืฉืœืžื™ื ืฉืœ 16 ืกื™ื‘ื™ื•ืช. ืขื‘ื•ืจ ืชืฆื•ืจื” ืžื”ื•ื“ืจืช, ื”ืฉื™ืžื•ืฉ ื‘ืกืคืจื™ื™ื” ื”ืžืขื•ื“ื ืช ืื™ื ื• ื—ื•ื‘ื”, ืืš ื”ื•ื ืžืฉืคืจ ืืช ื™ื›ื•ืœืช ื”ืžื”ื“ืจ ืœื‘ื“ื•ืง ืืช ื”ืชืฆื•ืจื”.

ืขื‘ื•ืจ ืคืจื•ื˜ื•ืงื•ืœื™ HTTP (REST), ื‘ื ื•ืกืฃ ืœืžืกืคืจ ื”ื™ืฆื™ืื”, ื™ื™ืชื›ืŸ ืฉื ืฆื˜ืจืš ื’ื ืืช ื”ื ืชื™ื‘ ืœืฉื™ืจื•ืช:

type UrlPathPrefix = Refined[String, MatchesRegex[W.`"[a-zA-Z_0-9/]*"`.T]]
case class PortWithPrefix[Protocol](portNumber: PortNumber, pathPrefix: UrlPathPrefix)

ืกื•ื’ื™ ืคืื ื˜ื•ื

ื›ื“ื™ ืœื–ื”ื•ืช ืืช ื”ืคืจื•ื˜ื•ืงื•ืœ ื‘ื–ืžืŸ ื”ืงื•ืžืคื™ืœืฆื™ื”, ืื ื• ืžืฉืชืžืฉื™ื ื‘ืคืจืžื˜ืจ type ืฉืื™ื ื• ื‘ืฉื™ืžื•ืฉ ื‘ืชื•ืš ื”ืžื—ืœืงื”. ื”ื—ืœื˜ื” ื–ื• ื ื•ื‘ืขืช ืžื”ืขื•ื‘ื“ื” ืฉืื ื• ืœื ืžืฉืชืžืฉื™ื ื‘ืžื•ืคืข ืคืจื•ื˜ื•ืงื•ืœ ื‘ื–ืžืŸ ืจื™ืฆื”, ืืš ื ืจืฆื” ืฉื”ืžื”ื“ืจ ื™ื‘ื“ื•ืง ืชืื™ืžื•ืช ืœืคืจื•ื˜ื•ืงื•ืœ. ืขืœ ื™ื“ื™ ืฆื™ื•ืŸ ื”ืคืจื•ื˜ื•ืงื•ืœ, ืœื ื ื•ื›ืœ ืœื”ืขื‘ื™ืจ ืฉื™ืจื•ืช ืœื ื”ื•ืœื ื›ืชืœื•ืช.

ืื—ื“ ื”ืคืจื•ื˜ื•ืงื•ืœื™ื ื”ื ืคื•ืฆื™ื ื”ื•ื ื”-REST API ืขื ื”ืกื“ืจืช Json:

sealed trait JsonHttpRestProtocol[RequestMessage, ResponseMessage]

ืื™ืคื” RequestMessage - ืกื•ื’ ื‘ืงืฉื”, ResponseMessage - ืกื•ื’ ืชื’ื•ื‘ื”.
ื›ืžื•ื‘ืŸ, ืื ื• ื™ื›ื•ืœื™ื ืœื”ืฉืชืžืฉ ื‘ืชื™ืื•ืจื™ ืคืจื•ื˜ื•ืงื•ืœ ืื—ืจื™ื ื”ืžืกืคืงื™ื ืืช ื“ื™ื•ืง ื”ืชื™ืื•ืจ ืฉืื ื• ื“ื•ืจืฉื™ื.

ืœืžื˜ืจื•ืช ืคื•ืกื˜ ื–ื”, ื ืฉืชืžืฉ ื‘ื’ืจืกื” ืคืฉื•ื˜ื” ืฉืœ โ€‹โ€‹ื”ืคืจื•ื˜ื•ืงื•ืœ:

sealed trait SimpleHttpGetRest[RequestMessage, ResponseMessage]

ื›ืืŸ ื”ื‘ืงืฉื” ื”ื™ื ืžื—ืจื•ื–ืช ื”ืžืฆื•ืจืคืช ืœื›ืชื•ื‘ืช ื”-URL ื•ื”ืชื’ื•ื‘ื” ื”ื™ื ื”ืžื—ืจื•ื–ืช ื”ืžื•ื—ื–ืจืช ื‘ื’ื•ืฃ ืชื’ื•ื‘ืช ื”-HTTP.

ืชืฆื•ืจืช ื”ืฉื™ืจื•ืช ืžืชื•ืืจืช ืœืคื™ ืฉื ื”ืฉื™ืจื•ืช, ื”ื™ืฆื™ืื•ืช ื•ื”ืชืœื•ืช. ืืœืžื ื˜ื™ื ืืœื” ื™ื›ื•ืœื™ื ืœื”ื™ื•ืช ืžื™ื•ืฆื’ื™ื ื‘ืกืงืืœื” ื‘ื›ืžื” ื“ืจื›ื™ื (ืœื“ื•ื’ืžื”, HList-s, ืกื•ื’ื™ ื ืชื•ื ื™ื ืืœื’ื‘ืจื™ื™ื). ืœืžื˜ืจื•ืช ืคื•ืกื˜ ื–ื”, ื ืฉืชืžืฉ ื‘ืชื‘ื ื™ืช ื”ืขื•ื’ื” ื•ื ืฆื™ื’ ืžื•ื“ื•ืœื™ื ื”ืžืฉืชืžืฉื™ื trait'ืื•ื‘. (ื“ืคื•ืก ื”ืขื•ื’ื” ืื™ื ื• ืžืจื›ื™ื‘ ื ื“ืจืฉ ื‘ื’ื™ืฉื” ื–ื•. ื”ื•ื ืคืฉื•ื˜ ื™ื™ืฉื•ื ืืคืฉืจื™ ืื—ื“).

ืชืœื•ืช ื‘ื™ืŸ ืฉื™ืจื•ืชื™ื ื™ื›ื•ืœื” ืœื”ื™ื•ืช ืžื™ื•ืฆื’ืช ื›ืฉื™ื˜ื•ืช ื”ืžื—ื–ื™ืจื•ืช ื™ืฆื™ืื•ืช EndPointืฉืœ ืฆืžืชื™ื ืื—ืจื™ื:

  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)
  }

ื›ื“ื™ ืœื™ืฆื•ืจ ืฉื™ืจื•ืช ื”ื“, ื›ืœ ืžื” ืฉืืชื” ืฆืจื™ืš ื”ื•ื ืžืกืคืจ ื™ืฆื™ืื” ื•ืื™ื ื“ื™ืงืฆื™ื” ืœื›ืš ืฉื”ื™ืฆื™ืื” ืชื•ืžื›ืช ื‘ืคืจื•ื˜ื•ืงื•ืœ ื”ื“. ื™ื™ืชื›ืŸ ืฉืœื ื ืฆื™ื™ืŸ ื™ืฆื™ืื” ืกืคืฆื™ืคื™ืช, ื›ื™... ืชื›ื•ื ื•ืช ืžืืคืฉืจื•ืช ืœืš ืœื”ื›ืจื™ื– ืขืœ ืฉื™ื˜ื•ืช ืœืœื ื™ื™ืฉื•ื (ืฉื™ื˜ื•ืช ืžื•ืคืฉื˜ื•ืช). ื‘ืžืงืจื” ื–ื”, ื‘ืขืช ื™ืฆื™ืจืช ืชืฆื•ืจื” ืงื•ื ืงืจื˜ื™ืช, ื”ืžื”ื“ืจ ื™ื“ืจื•ืฉ ืžืื™ืชื ื• ืœืกืคืง ื™ื™ืฉื•ื ืฉืœ ื”ืฉื™ื˜ื” ื”ืžื•ืคืฉื˜ืช ื•ืœืกืคืง ืžืกืคืจ ื™ืฆื™ืื”. ืžื›ื™ื•ื•ืŸ ืฉื”ื˜ืžืขื ื• ืืช ื”ืฉื™ื˜ื”, ื‘ืขืช ื™ืฆื™ืจืช ืชืฆื•ืจื” ืกืคืฆื™ืคื™ืช, ื™ื™ืชื›ืŸ ืฉืœื ื ืฆื™ื™ืŸ ื™ืฆื™ืื” ืื—ืจืช. ืขืจืš ื‘ืจื™ืจืช ื”ืžื—ื“ืœ ื™ืฉืžืฉ.

ื‘ืชืฆื•ืจืช ื”ืœืงื•ื— ืื ื• ืžื›ืจื™ื–ื™ื ืขืœ ืชืœื•ืช ื‘ืฉื™ืจื•ืช ื”ื“:

  trait EchoClientConfig[A] {
    def testMessage: String = "test"
    def pollInterval: FiniteDuration
    def echoServiceDependency: HttpSimpleGetEndPoint[_, EchoProtocol[A]]
  }

ื”ืชืœื•ืช ื”ื™ื ืžืื•ืชื• ืกื•ื’ ืฉืœ ื”ืฉื™ืจื•ืช ื”ืžื™ื•ืฆื echoService. ื‘ืคืจื˜, ื‘-echo client ืื ื• ื“ื•ืจืฉื™ื ืืช ืื•ืชื• ืคืจื•ื˜ื•ืงื•ืœ. ืœื›ืŸ, ื›ืืฉืจ ืžื—ื‘ืจื™ื ืฉื ื™ ืฉื™ืจื•ืชื™ื, ืื ื• ื™ื›ื•ืœื™ื ืœื”ื™ื•ืช ื‘ื˜ื•ื—ื™ื ืฉื”ื›ืœ ื™ืขื‘ื•ื“ ื›ืžื• ืฉืฆืจื™ืš.

ื”ื˜ืžืขืช ืฉื™ืจื•ืชื™ื

ื ื“ืจืฉืช ืคื•ื ืงืฆื™ื” ื›ื“ื™ ืœื”ืคืขื™ืœ ื•ืœื”ืคืกื™ืง ืืช ื”ืฉื™ืจื•ืช. (ื”ื™ื›ื•ืœืช ืœืขืฆื•ืจ ืฉื™ืจื•ืช ื”ื™ื ืงืจื™ื˜ื™ืช ืœื‘ื“ื™ืงื”.) ืฉื•ื‘, ื™ืฉื ืŸ ืžืกืคืจ ืืคืฉืจื•ื™ื•ืช ืœื™ื™ืฉื•ื ืชื›ื•ื ื” ื›ื–ื• (ืœื“ื•ื’ืžื”, ื ื•ื›ืœ ืœื”ืฉืชืžืฉ ื‘ืžื—ืœืงื•ืช ืกื•ื’ ื”ืžื‘ื•ืกืกื•ืช ืขืœ ืกื•ื’ ื”ืชืฆื•ืจื”). ืœืžื˜ืจื•ืช ืคื•ืกื˜ ื–ื” ื ืฉืชืžืฉ ื‘ืชื‘ื ื™ืช ื”ืขื•ื’ื”. ื ืฆื™ื’ ืืช ื”ืฉื™ืจื•ืช ื‘ืืžืฆืขื•ืช ืžื—ืœืงื” cats.Resource, ื›ื™ ืžื—ืœืงื” ื–ื• ื›ื‘ืจ ืžืกืคืงืช ืืžืฆืขื™ื ืœื”ื‘ื˜ื™ื— ื‘ื‘ื˜ื—ื” ืฉื—ืจื•ืจ ืžืฉืื‘ื™ื ื‘ืžืงืจื” ืฉืœ ื‘ืขื™ื•ืช. ื›ื“ื™ ืœืงื‘ืœ ืžืฉืื‘, ืขืœื™ื ื• ืœืกืคืง ืชืฆื•ืจื” ื•ื”ืงืฉืจ ืฉืœ ื–ืžืŸ ืจื™ืฆื” ืžื•ื›ืŸ. ืคื•ื ืงืฆื™ื™ืช ื”ืคืขืœืช ื”ืฉื™ืจื•ืช ื™ื›ื•ืœื” ืœื”ื™ืจืื•ืช ื›ืš:

  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 - ืื•ื‘ื™ื™ืงื˜ ื–ืžืŸ ืจื™ืฆื” ื”ืžืืคืฉืจ ืœืš ืœื’ืœื•ืช ืืช ื”ื›ืชื•ื‘ื•ืช ืฉืœ ืฆืžืชื™ื ืื—ืจื™ื (ืจืื” ืœื”ืœืŸ)

ื•ืกื•ื’ื™ื ื ื•ืกืคื™ื ืžื”ืกืคืจื™ื™ื” cats:

  • F[_] - ืกื•ื’ ื”ืืคืงื˜ (ื‘ืžืงืจื” ื”ืคืฉื•ื˜ ื‘ื™ื•ืชืจ F[A] ื™ื›ื•ืœ ืœื”ื™ื•ืช ืจืง ืคื•ื ืงืฆื™ื” () => A. ื‘ืคื•ืกื˜ ื–ื” ื ืฉืชืžืฉ cats.IO.)
  • Reader[A,B] - ืคื—ื•ืช ืื• ื™ื•ืชืจ ืฉื ื ืจื“ืฃ ืœืคื•ื ืงืฆื™ื” A => B
  • cats.Resource - ืžืฉืื‘ ืฉื ื™ืชืŸ ืœื”ืฉื™ื’ ื•ืœืฉื—ืจืจ
  • Timer - ื˜ื™ื™ืžืจ (ืžืืคืฉืจ ืœืš ืœื”ื™ืจื“ื ืœื–ืžืŸ ืžื” ื•ืœืžื“ื•ื“ ืžืจื•ื•ื—ื™ ื–ืžืŸ)
  • ContextShift - ืื ืœื•ื’ื™ ExecutionContext
  • Applicative - ืžื—ืœืงื” ืžืกื•ื’ ืืคืงื˜ ื”ืžืืคืฉืจืช ืœืฉืœื‘ ืืคืงื˜ื™ื ื‘ื•ื“ื“ื™ื (ื›ืžืขื˜ ืžื•ื ืื“ื”). ื‘ื™ื™ืฉื•ืžื™ื ืžื•ืจื›ื‘ื™ื ื™ื•ืชืจ ื ืจืื” ืฉืขื“ื™ืฃ ืœื”ืฉืชืžืฉ ื‘ื• Monad/ConcurrentEffect.

ื‘ืืžืฆืขื•ืช ื—ืชื™ืžืช ืคื•ื ืงืฆื™ื” ื–ื• ื ื•ื›ืœ ืœื™ื™ืฉื ืžืกืคืจ ืฉื™ืจื•ืชื™ื. ืœื“ื•ื’ืžื”, ืฉื™ืจื•ืช ืฉืœื ืขื•ืฉื” ื›ืœื•ื:

  trait ZeroServiceImpl[F[_]] extends ServiceImpl[F] {
    type Config <: Any
    def resource(...): ResourceReader[F, Config, Unit] =
      Reader(_ => Resource.pure[F, Unit](()))
  }

(ืก"ืž. ืงื•ื“ ื”ืžืงื•ืจ, ืฉื‘ื”ื ืžื™ื•ืฉืžื™ื ืฉื™ืจื•ืชื™ื ืื—ืจื™ื - ืฉื™ืจื•ืช ื”ื“, ืืงื• ืœืงื•ื—
ะธ ื‘ืงืจื™ื ืœื›ืœ ื”ื—ื™ื™ื.)

ืฆื•ืžืช ื”ื•ื ืื•ื‘ื™ื™ืงื˜ ืฉื™ื›ื•ืœ ืœื”ืคืขื™ืœ ืžืกืคืจ ืฉื™ืจื•ืชื™ื (ื”ืฉืงื” ืฉืœ ืฉืจืฉืจืช ืžืฉืื‘ื™ื ืžื•ื‘ื˜ื—ืช ืขืœ ื™ื“ื™ ืชื‘ื ื™ืช ื”ืขื•ื’ื”):

object SingleNodeImpl extends ZeroServiceImpl[IO]
  with EchoServiceService
  with EchoClientService
  with FiniteDurationLifecycleServiceImpl
{
  type Config = EchoConfig[String] with EchoClientConfig[String] with FiniteDurationLifecycleConfig
}

ืฉื™ื ืœื‘ ืฉืื ื• ืžืฆื™ื™ื ื™ื ืืช ืกื•ื’ ื”ืชืฆื•ืจื” ื”ืžื“ื•ื™ืง ื”ื ื“ืจืฉ ืขื‘ื•ืจ ืฆื•ืžืช ื–ื”. ืื ื ืฉื›ื— ืœืฆื™ื™ืŸ ืืช ืื—ื“ ืžืกื•ื’ื™ ื”ืชืฆื•ืจื” ื”ื ื“ืจืฉื™ื ืขืœ ื™ื“ื™ ืฉื™ืจื•ืช ืžืกื•ื™ื, ืชื”ื™ื” ืฉื’ื™ืืช ืงื•ืžืคื™ืœืฆื™ื”. ื›ืžื• ื›ืŸ, ืœื ื ื•ื›ืœ ืœื”ืคืขื™ืœ ืฆื•ืžืช ืืœื ืื ื ืกืคืง ืื•ื‘ื™ื™ืงื˜ ื›ืœืฉื”ื• ืžื”ืกื•ื’ ื”ืžืชืื™ื ืขื ื›ืœ ื”ื ืชื•ื ื™ื ื”ื“ืจื•ืฉื™ื.

ืจื–ื•ืœื•ืฆื™ื™ืช ืฉื ืžืืจื—

ื›ื“ื™ ืœื”ืชื—ื‘ืจ ืœืžืืจื— ืžืจื•ื—ืง, ืื ื—ื ื• ืฆืจื™ื›ื™ื ื›ืชื•ื‘ืช IP ืืžื™ืชื™ืช. ื™ื™ืชื›ืŸ ืฉื”ื›ืชื•ื‘ืช ืชื™ื•ื•ื“ืข ืžืื•ื—ืจ ื™ื•ืชืจ ืžืฉืืจ ื”ืชืฆื•ืจื”. ืื– ืื ื—ื ื• ืฆืจื™ื›ื™ื ืคื•ื ืงืฆื™ื” ืฉืžืžืคื” ืืช ืžื–ื”ื” ื”ืฆื•ืžืช ืœื›ืชื•ื‘ืช:

case class NodeAddress[NodeId](host: Uri.Host)
trait AddressResolver[F[_]] {
  def resolve[NodeId](nodeId: NodeId): F[NodeAddress[NodeId]]
}

ื™ืฉื ืŸ ืžืกืคืจ ื“ืจื›ื™ื ืœื™ื™ืฉื ืคื•ื ืงืฆื™ื” ื–ื•:

  1. ืื ื”ื›ืชื•ื‘ื•ืช ื ื•ื“ืขื•ืช ืœื ื• ืœืคื ื™ ื”ืคืจื™ืกื”, ืื– ื ื•ื›ืœ ืœื™ืฆื•ืจ ืงื•ื“ Scala ืขื
    ื›ืชื•ื‘ื•ืช ื•ืœืื—ืจ ืžื›ืŸ ื”ืคืขืœ ืืช ื”-build. ื–ื” ื™ืงืžืคืœ ื•ื™ืคืขื™ืœ ื‘ื“ื™ืงื•ืช.
    ื‘ืžืงืจื” ื–ื”, ื”ืคื•ื ืงืฆื™ื” ืชื”ื™ื” ื™ื“ื•ืขื” ื‘ืื•ืคืŸ ืกื˜ื˜ื™ ื•ื ื™ืชืŸ ืœื™ื™ืฆื’ ืื•ืชื” ื‘ืงื•ื“ ื›ืžื™ืคื•ื™ Map[NodeId, NodeAddress].
  2. ื‘ืžืงืจื™ื ืžืกื•ื™ืžื™ื, ื”ื›ืชื•ื‘ืช ื‘ืคื•ืขืœ ื™ื“ื•ืขื” ืจืง ืœืื—ืจ ืฉื”ืฆื•ืžืช ื”ืชื—ื™ืœ.
    ื‘ืžืงืจื” ื–ื”, ื ื•ื›ืœ ืœื™ื™ืฉื "ืฉื™ืจื•ืช ื’ื™ืœื•ื™" ืฉืคื•ืขืœ ืœืคื ื™ ืฆืžืชื™ื ืื—ืจื™ื ื•ื›ืœ ื”ืฆืžืชื™ื ื™ืจืฉืžื• ืœืฉื™ืจื•ืช ื–ื” ื•ื™ื‘ืงืฉื• ืืช ื”ื›ืชื•ื‘ื•ืช ืฉืœ ืฆืžืชื™ื ืื—ืจื™ื.
  3. ืื ื ื•ื›ืœ ืœืฉื ื•ืช /etc/hosts, ืื– ืืชื” ื™ื›ื•ืœ ืœื”ืฉืชืžืฉ ื‘ืฉืžื•ืช ืžืืจื—ื™ื ืžื•ื’ื“ืจื™ื ืžืจืืฉ (ื›ืžื• my-project-main-node ะธ echo-backend) ื•ืคืฉื•ื˜ ืžืงืฉืจื™ื ืืช ื”ืฉืžื•ืช ื”ืืœื”
    ืขื ื›ืชื•ื‘ื•ืช IP ื‘ืžื”ืœืš ื”ืคืจื™ืกื”.

ื‘ืคื•ืกื˜ ื–ื” ืœื ื ืฉืงื•ืœ ืžืงืจื™ื ืืœื• ื‘ื™ืชืจ ืคื™ืจื•ื˜. ื‘ืฉื‘ื™ืœ ืฉืœื ื•
ื‘ื“ื•ื’ืžื” ืฆืขืฆื•ืข, ืœื›ืœ ื”ืฆืžืชื™ื ืชื”ื™ื” ืื•ืชื” ื›ืชื•ื‘ืช IP - 127.0.0.1.

ืœืื—ืจ ืžื›ืŸ, ื ืฉืงื•ืœ ืฉืชื™ ืืคืฉืจื•ื™ื•ืช ืขื‘ื•ืจ ืžืขืจื›ืช ืžื‘ื•ื–ืจืช:

  1. ื”ืฆื‘ืช ื›ืœ ื”ืฉื™ืจื•ืชื™ื ืขืœ ืฆื•ืžืช ืื—ื“.
  2. ื•ืื™ืจื•ื— ืฉืœ ืฉื™ืจื•ืช ื”ื”ื“ ื•ืœืงื•ื— ื”ื”ื“ ื‘ืฆืžืชื™ื ืฉื•ื ื™ื.

ืชืฆื•ืจื” ืขื‘ื•ืจ ืฆื•ืžืช ืื—ื“:

ืชืฆื•ืจืช ืฆื•ืžืช ื‘ื•ื“ื“

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.
}

ื”ืื•ื‘ื™ื™ืงื˜ ืžื™ื™ืฉื ืืช ื”ืชืฆื•ืจื” ืฉืœ ื”ืœืงื•ื— ื•ื’ื ืฉืœ ื”ืฉืจืช. ื ืขืฉื” ืฉื™ืžื•ืฉ ื’ื ื‘ืชืฆื•ืจื” ืฉืœ ื–ืžืŸ ื—ื™ื™ื ื›ืš ืฉืื—ืจื™ ื”ืžืจื•ื•ื— lifetime ืœื”ืคืกื™ืง ืืช ื”ืชื•ื›ื ื™ืช. (Ctrl-C ื’ื ืขื•ื‘ื“ ื•ืžืฉื—ืจืจ ืืช ื›ืœ ื”ืžืฉืื‘ื™ื ื‘ืฆื•ืจื” ื ื›ื•ื ื”.)

ื ื™ืชืŸ ืœื”ืฉืชืžืฉ ื‘ืื•ืชื” ืงื‘ื•ืฆื” ืฉืœ ืชื›ื•ื ื•ืช ืชืฆื•ืจื” ื•ื”ื˜ืžืขื” ืœื™ืฆื™ืจืช ืžืขืจื›ืช ื”ืžื•ืจื›ื‘ืช ืž ืฉื ื™ ืฆืžืชื™ื ื ืคืจื“ื™ื:

ืชืฆื•ืจืช ืฉื ื™ ืฆืžืชื™ื

  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"
  }

ื—ึธืฉืื•ึผื‘! ืฉื™ืžื• ืœื‘ ื›ื™ืฆื“ ื”ืฉื™ืจื•ืชื™ื ืžืงื•ืฉืจื™ื. ืื ื• ืžืฆื™ื™ื ื™ื ืฉื™ืจื•ืช ื”ืžื™ื•ืฉื ืขืœ ื™ื“ื™ ืฆื•ืžืช ืื—ื“ ื›ื™ื™ืฉื•ื ืฉืœ ืฉื™ื˜ืช ื”ืชืœื•ืช ืฉืœ ืฆื•ืžืช ืื—ืจ. ืกื•ื’ ื”ืชืœื•ืช ื ื‘ื“ืง ืขืœ ื™ื“ื™ ื”ืžื”ื“ืจ, ื›ื™ ืžื›ื™ืœ ืืช ืกื•ื’ ื”ืคืจื•ื˜ื•ืงื•ืœ. ื‘ืขืช ื”ืคืขืœื”, ื”ืชืœื•ืช ืชื›ื™ืœ ืืช ืžื–ื”ื” ืฆื•ืžืช ื”ื™ืขื“ ื”ื ื›ื•ืŸ. ื”ื•ื“ื•ืช ืœืชื›ื ื™ืช ื–ื•, ืื ื• ืžืฆื™ื™ื ื™ื ืืช ืžืกืคืจ ื”ื™ืฆื™ืื” ืคืขื ืื—ืช ื‘ื“ื™ื•ืง ื•ืชืžื™ื“ ืžื•ื‘ื˜ื— ืœื ื• ืœื”ืชื™ื™ื—ืก ืœื™ืฆื™ืื” ื”ื ื›ื•ื ื”.

ื”ื˜ืžืขืช ืฉื ื™ ืฆืžืชื™ ืžืขืจื›ืช

ืขื‘ื•ืจ ืชืฆื•ืจื” ื–ื•, ืื ื• ืžืฉืชืžืฉื™ื ื‘ืื•ืชื ื™ื™ืฉื•ืžื™ ืฉื™ืจื•ืช ืœืœื ืฉื™ื ื•ื™ื™ื. ื”ื”ื‘ื“ืœ ื”ื™ื—ื™ื“ ื”ื•ื ืฉืขื›ืฉื™ื• ื™ืฉ ืœื ื• ืฉื ื™ ืื•ื‘ื™ื™ืงื˜ื™ื ืฉืžื™ื™ืฉืžื™ื ืกื˜ื™ื ืฉื•ื ื™ื ืฉืœ ืฉื™ืจื•ืชื™ื:

  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
  }

ื”ืฆื•ืžืช ื”ืจืืฉื•ืŸ ืžื™ื™ืฉื ืืช ื”ืฉืจืช ื•ืฆืจื™ืš ืจืง ืชืฆื•ืจืช ืฉืจืช. ื”ืฆื•ืžืช ื”ืฉื ื™ ืžื™ื™ืฉื ืืช ื”ืœืงื•ื— ื•ืžืฉืชืžืฉ ื‘ื—ืœืง ืื—ืจ ืฉืœ ื”ืชืฆื•ืจื”. ื›ืžื• ื›ืŸ, ืฉื ื™ ื”ืฆืžืชื™ื ื–ืงื•ืงื™ื ืœื ื™ื”ื•ืœ ืœื›ืœ ื”ื—ื™ื™ื. ืฆื•ืžืช ื”ืฉืจืช ืคื•ืขืœ ืœืœื ื”ื’ื‘ืœืช ื–ืžืŸ ืขื“ ืฉื”ื•ื ื ืขืฆืจ SIGTERMืื•ื, ื•ืฆื•ืžืช ื”ืœืงื•ื— ืžืกืชื™ื™ื ืœืื—ืจ ื–ืžืŸ ืžื”. ืก"ืž. ืืคืœื™ืงืฆื™ื™ืช ืžืฉื’ืจ.

ืชื”ืœื™ืš ืคื™ืชื•ื— ื›ืœืœื™

ื‘ื•ืื• ื ืจืื” ื›ื™ืฆื“ ื’ื™ืฉืช ื”ืชืฆื•ืจื” ื”ื–ื• ืžืฉืคื™ืขื” ืขืœ ืชื”ืœื™ืš ื”ืคื™ืชื•ื— ื”ื›ื•ืœืœ.

ื”ืชืฆื•ืจื” ืชืงื•ืžืคืœ ื™ื—ื“ ืขื ืฉืืจ ื”ืงื•ื“ ื•ื™ื™ื•ื•ืฆืจ ื—ืคืฅ (.jar). ื ืจืื” ื”ื’ื™ื•ื ื™ ืœืฉื™ื ืืช ื”ืชืฆื•ืจื” ื‘ื—ืคืฅ ื ืคืจื“. ื”ืกื™ื‘ื” ืœื›ืš ื”ื™ื ืฉื™ื›ื•ืœื•ืช ืœื”ื™ื•ืช ืœื ื• ืžืกืคืจ ืชืฆื•ืจื•ืช ื”ืžื‘ื•ืกืกื•ืช ืขืœ ืื•ืชื• ืงื•ื“. ืฉื•ื‘, ื ื™ืชืŸ ืœื™ืฆื•ืจ ื—ืคืฆื™ื ื”ืชื•ืืžื™ื ืœืขื ืคื™ ืชืฆื•ืจื” ืฉื•ื ื™ื. ื”ืชืœื•ืช ื‘ื’ืจืกืื•ืช ืกืคืฆื™ืคื™ื•ืช ืฉืœ ืกืคืจื™ื•ืช ื ืฉืžืจื•ืช ื™ื—ื“ ืขื ื”ืชืฆื•ืจื”, ื•ื’ืจืกืื•ืช ืืœื• ื ืฉืžืจื•ืช ืœื ืฆื— ื‘ื›ืœ ืคืขื ืฉืื ื• ืžื—ืœื™ื˜ื™ื ืœืคืจื•ืก ืืช ื”ื’ืจืกื” ื”ื–ื• ืฉืœ ื”ืชืฆื•ืจื”.

ื›ืœ ืฉื™ื ื•ื™ ืชืฆื•ืจื” ื”ื•ืคืš ืœืฉื™ื ื•ื™ ืงื•ื“. ื•ืœื›ืŸ, ื›ืœ ืื—ื“
ื”ืฉื™ื ื•ื™ ื™ื›ื•ืกื” ื‘ืชื”ืœื™ืš ืื‘ื˜ื—ืช ื”ืื™ื›ื•ืช ื”ืจื’ื™ืœ:

ื›ืจื˜ื™ืก ื‘ืžืขืงื‘ ืื—ืจ ื‘ืื’ื™ื -> ื™ื—ืกื™ ืฆื™ื‘ื•ืจ -> ืกืงื™ืจื” -> ืžื™ื–ื•ื’ ืขื ืกื ื™ืคื™ื ืจืœื•ื•ื ื˜ื™ื™ื ->
ืื™ื ื˜ื’ืจืฆื™ื” -> ืคืจื™ืกื”

ื”ื”ืฉืœื›ื•ืช ื”ืขื™ืงืจื™ื•ืช ืฉืœ ื™ื™ืฉื•ื ืชืฆื•ืจื” ืžื”ื•ื“ืจืช ื”ืŸ:

  1. ื”ืชืฆื•ืจื” ืชื”ื™ื” ืขืงื‘ื™ืช ื‘ื›ืœ ื”ืฆืžืชื™ื ืฉืœ ื”ืžืขืจื›ืช ื”ืžื‘ื•ื–ืจืช. ื‘ืฉืœ ื”ืขื•ื‘ื“ื” ืฉื›ืœ ื”ืฆืžืชื™ื ืžืงื‘ืœื™ื ืืช ืื•ืชื” ืชืฆื•ืจื” ืžืžืงื•ืจ ื™ื—ื™ื“.

  2. ื–ื” ื‘ืขื™ื™ืชื™ ืœืฉื ื•ืช ืืช ื”ืชืฆื•ืจื” ืจืง ื‘ืื—ื“ ืžื”ืฆืžืชื™ื. ืœื›ืŸ, "ืกื—ืฃ ืชืฆื•ืจื”" ืื™ื ื• ืกื‘ื™ืจ.

  3. ื–ื” ื”ื•ืคืš ืœื”ื™ื•ืช ืงืฉื” ื™ื•ืชืจ ืœื‘ืฆืข ืฉื™ื ื•ื™ื™ื ืงื˜ื ื™ื ื‘ืชืฆื•ืจื”.

  4. ืจื•ื‘ ืฉื™ื ื•ื™ื™ ื”ืชืฆื•ืจื” ื™ืชืจื—ืฉื• ื›ื—ืœืง ืžืชื”ืœื™ืš ื”ืคื™ืชื•ื— ื”ื›ื•ืœืœ ื•ื™ื”ื™ื• ื›ืคื•ืคื™ื ืœื‘ื“ื™ืงื”.

ื”ืื ืื ื™ ืฆืจื™ืš ืžืื’ืจ ื ืคืจื“ ื›ื“ื™ ืœืื—ืกืŸ ืืช ืชืฆื•ืจืช ื”ื™ื™ืฆื•ืจ? ืชืฆื•ืจื” ื–ื• ืขืฉื•ื™ื” ืœื”ื›ื™ืœ ืกื™ืกืžืื•ืช ื•ืžื™ื“ืข ืจื’ื™ืฉ ืื—ืจ ืืœื™ื”ื ื ืจืฆื” ืœื”ื’ื‘ื™ืœ ืืช ื”ื’ื™ืฉื”. ื‘ื”ืชื‘ืกืก ืขืœ ื–ื”, ื ืจืื” ื”ื’ื™ื•ื ื™ ืœืื—ืกืŸ ืืช ื”ืชืฆื•ืจื” ื”ืกื•ืคื™ืช ื‘ืžืื’ืจ ื ืคืจื“. ืืชื” ื™ื›ื•ืœ ืœืคืฆืœ ืืช ื”ืชืฆื•ืจื” ืœืฉื ื™ ื—ืœืงื™ื - ืื—ื“ ื”ืžื›ื™ืœ ื”ื’ื“ืจื•ืช ืชืฆื•ืจื” ื ื’ื™ืฉื•ืช ืœืฆื™ื‘ื•ืจ ื•ืื—ื“ ื”ืžื›ื™ืœ ื”ื’ื“ืจื•ืช ืžื•ื’ื‘ืœื•ืช. ื–ื” ื™ืืคืฉืจ ืœืจื•ื‘ ื”ืžืคืชื—ื™ื ืœืงื‘ืœ ื’ื™ืฉื” ืœื”ื’ื“ืจื•ืช ื ืคื•ืฆื•ืช. ื”ืคืจื“ื” ื–ื• ืงืœื” ืœื”ืฉื’ื” ื‘ืืžืฆืขื•ืช ืชื›ื•ื ื•ืช ื‘ื™ื ื™ื™ื ื”ืžื›ื™ืœื•ืช ืขืจื›ื™ ื‘ืจื™ืจืช ืžื—ื“ืœ.

ื•ืจื™ืืฆื™ื•ืช ืืคืฉืจื™ื•ืช

ื”ื‘ื” ื ื ืกื” ืœื”ืฉื•ื•ืช ืืช ื”ืชืฆื•ืจื” ื”ืžื•ืจื›ื‘ืช ืขื ื›ืžื” ื—ืœื•ืคื•ืช ื ืคื•ืฆื•ืช:

  1. ืงื•ื‘ืฅ ื˜ืงืกื˜ ื‘ืžื—ืฉื‘ ื”ื™ืขื“.
  2. ื—ื ื•ืช ืžืคืชื—-ืขืจืš ืžืจื›ื–ื™ืช (etcd/zookeeper).
  3. ืจื›ื™ื‘ื™ ืชื”ืœื™ืš ืฉื ื™ืชืŸ ืœื”ื’ื“ื™ืจ/ืœื”ืคืขื™ืœ ืžื—ื“ืฉ ืžื‘ืœื™ ืœื”ืคืขื™ืœ ืžื—ื“ืฉ ืืช ื”ืชื”ืœื™ืš.
  4. ืื—ืกื•ืŸ ืชืฆื•ืจื” ืžื—ื•ืฅ ืœื—ืคืฆื™ื ื•ื‘ืงืจืช ื’ืจืกืื•ืช.

ืงื‘ืฆื™ ื˜ืงืกื˜ ืžืกืคืงื™ื ื’ืžื™ืฉื•ืช ืžืฉืžืขื•ืชื™ืช ืžื‘ื—ื™ื ืช ืฉื™ื ื•ื™ื™ื ืงื˜ื ื™ื. ืžื ื”ืœ ื”ืžืขืจื›ืช ื™ื›ื•ืœ ืœื”ื™ื›ื ืก ืœืฆื•ืžืช ื”ืžืจื•ื—ืง, ืœื‘ืฆืข ืฉื™ื ื•ื™ื™ื ื‘ืงื‘ืฆื™ื ื”ืžืชืื™ืžื™ื ื•ืœื”ืคืขื™ืœ ืžื—ื“ืฉ ืืช ื”ืฉื™ืจื•ืช. ืขื ื–ืืช, ืขื‘ื•ืจ ืžืขืจื›ื•ืช ื’ื“ื•ืœื•ืช, ื’ืžื™ืฉื•ืช ื›ื–ื• ืขืฉื•ื™ื” ืฉืœื ืœื”ื™ื•ืช ืจืฆื•ื™ื”. ื”ืฉื™ื ื•ื™ื™ื ืฉื‘ื•ืฆืขื• ืื™ื ื ืžืฉืื™ืจื™ื ืขืงื‘ื•ืช ื‘ืžืขืจื›ื•ืช ืื—ืจื•ืช. ืืฃ ืื—ื“ ืœื ืกื•ืงืจ ืืช ื”ืฉื™ื ื•ื™ื™ื. ืงืฉื” ืœืงื‘ื•ืข ืžื™ ื‘ื“ื™ื•ืง ื‘ื™ืฆืข ืืช ื”ืฉื™ื ื•ื™ื™ื ื•ืžืื™ื–ื• ืกื™ื‘ื”. ืฉื™ื ื•ื™ื™ื ืื™ื ื ื ื‘ื“ืงื™ื. ืื ื”ืžืขืจื›ืช ืžื•ืคืฆืช, ื”ืžื ื”ืœ ืขืฉื•ื™ ืœืฉื›ื•ื— ืœื‘ืฆืข ืืช ื”ืฉื™ื ื•ื™ ื”ืžืชืื™ื ื‘ืฆืžืชื™ื ืื—ืจื™ื.

(ื™ืฉ ืœืฆื™ื™ืŸ ื’ื ืฉืฉื™ืžื•ืฉ ื‘ืชืฆื•ืจื” ืžื”ื•ื“ืจืช ืœื ืกื•ื’ืจ ืืช ื”ืืคืฉืจื•ืช ืœื”ืฉืชืžืฉ ื‘ืงื‘ืฆื™ ื˜ืงืกื˜ ื‘ืขืชื™ื“. ื™ืกืคื™ืง ืœื”ื•ืกื™ืฃ ืžื ืชื— ื•ืžืืžืช ืฉืžื™ื™ืฆืจ ืืช ืื•ืชื• ื”ืกื•ื’ ื›ืžื• ืคืœื˜ Config, ื•ืืชื” ื™ื›ื•ืœ ืœื”ืฉืชืžืฉ ื‘ืงื‘ืฆื™ ื˜ืงืกื˜. ืžื™ื“ ื ื•ื‘ืข ืฉื”ืžื•ืจื›ื‘ื•ืช ืฉืœ ืžืขืจื›ืช ืขื ืชืฆื•ืจืช ืงื•ืžืคื™ืœืฆื™ื” ืงื˜ื ื” ื‘ืžืขื˜ ืžื”ืžื•ืจื›ื‘ื•ืช ืฉืœ ืžืขืจื›ืช ื”ืžืฉืชืžืฉืช ื‘ืงื‘ืฆื™ ื˜ืงืกื˜, ืžื›ื™ื•ื•ืŸ ืงื•ื‘ืฆื™ ื˜ืงืกื˜ ื“ื•ืจืฉื™ื ืงื•ื“ ื ื•ืกืฃ.)

ืžืื’ืจ ืžืคืชื—-ืขืจืš ืžืจื›ื–ื™ ื”ื•ื ืžื ื’ื ื•ืŸ ื˜ื•ื‘ ืœื”ืคืฆืช ืžื˜ื ืคืจืžื˜ืจื™ื ืฉืœ ื™ื™ืฉื•ื ืžื‘ื•ื–ืจ. ืื ื—ื ื• ืฆืจื™ื›ื™ื ืœื”ื—ืœื™ื˜ ืžื” ื”ื ืคืจืžื˜ืจื™ ืชืฆื•ืจื” ื•ืžื” ื”ื ืจืง ื ืชื•ื ื™ื. ืชื ื• ืœื ื• ืคื•ื ืงืฆื™ื” C => A => B, ื•ื”ืคืจืžื˜ืจื™ื C ืžืฉืชื ื” ืœืขืชื™ื ืจื—ื•ืงื•ืช, ื•ื ืชื•ื ื™ื A - ืœืขืชื™ื ืงืจื•ื‘ื•ืช. ื‘ืžืงืจื” ื”ื–ื” ืืคืฉืจ ืœื”ื’ื™ื“ ืืช ื–ื” C - ืคืจืžื˜ืจื™ ืชืฆื•ืจื”, ื• A - ื ืชื•ื ื™ื. ื ืจืื” ื›ื™ ืคืจืžื˜ืจื™ ืชืฆื•ืจื” ืฉื•ื ื™ื ืžื”ื ืชื•ื ื™ื ื‘ื›ืš ืฉื”ื ื‘ื“ืจืš ื›ืœืœ ืžืฉืชื ื™ื ื‘ืชื“ื™ืจื•ืช ื ืžื•ื›ื” ื™ื•ืชืจ ืžืืฉืจ ื ืชื•ื ื™ื. ื›ืžื• ื›ืŸ, ื ืชื•ื ื™ื ื‘ื“ืจืš ื›ืœืœ ืžื’ื™ืขื™ื ืžืžืงื•ืจ ืื—ื“ (ืžื”ืžืฉืชืžืฉ), ื•ืคืจืžื˜ืจื™ ืชืฆื•ืจื” ืžืžืงื•ืจ ืื—ืจ (ืžืžื ื”ืœ ื”ืžืขืจื›ืช).

ืื ืœืขืชื™ื ื ื“ื™ืจื•ืช ื™ืฉ ืœืขื“ื›ืŸ ืคืจืžื˜ืจื™ื ื”ืžืฉืชื ื™ื ืžื‘ืœื™ ืœื”ืคืขื™ืœ ืžื—ื“ืฉ ืืช ื”ืชื•ื›ื ื™ืช, ืื– ื–ื” ื™ื›ื•ืœ ืœื”ื•ื‘ื™ืœ ืœืขืชื™ื ืงืจื•ื‘ื•ืช ืœืกื™ื‘ื•ืš ืฉืœ ื”ืชื•ื›ื ื™ืช, ืžื›ื™ื•ื•ืŸ ืฉื ืฆื˜ืจืš ืื™ื›ืฉื”ื• ืœืกืคืง ืคืจืžื˜ืจื™ื, ืœืื—ืกืŸ, ืœื ืชื— ื•ืœื‘ื“ื•ืง ื•ืœืขื‘ื“ ืขืจื›ื™ื ืฉื’ื•ื™ื™ื. ืœื›ืŸ, ืžื ืงื•ื“ืช ื”ืžื‘ื˜ ืฉืœ ื”ืคื—ืชืช ื”ืžื•ืจื›ื‘ื•ืช ืฉืœ ื”ืชื•ื›ื ื™ืช, ื”ื’ื™ื•ื ื™ ืœืฆืžืฆื ืืช ืžืกืคืจ ื”ืคืจืžื˜ืจื™ื ืฉื™ื›ื•ืœื™ื ืœื”ืฉืชื ื•ืช ื‘ืžื”ืœืš ืคืขื•ืœืช ื”ืชื•ื›ื ื™ืช (ืื• ืœื ืœืชืžื•ืš ื‘ืคืจืžื˜ืจื™ื ื›ืืœื” ื‘ื›ืœืœ).

ืœืฆื•ืจืš ื”ืคื•ืกื˜ ื”ื–ื”, ื ื‘ื“ื™ืœ ื‘ื™ืŸ ืคืจืžื˜ืจื™ื ืกื˜ื˜ื™ื™ื ื•ื“ื™ื ืืžื™ื™ื. ืื ื”ื”ื™ื’ื™ื•ืŸ ืฉืœ ื”ืฉื™ืจื•ืช ื“ื•ืจืฉ ืฉื™ื ื•ื™ ืคืจืžื˜ืจื™ื ื‘ืžื”ืœืš ืคืขื•ืœืช ื”ืชื•ื›ื ื™ืช, ืื–ื™ ื ืงืจื ืœืคืจืžื˜ืจื™ื ื›ืืœื” ื“ื™ื ืžื™ื™ื. ืื—ืจืช ื”ืืคืฉืจื•ื™ื•ืช ื”ืŸ ืกื˜ื˜ื™ื•ืช ื•ื ื™ืชืŸ ืœื”ื’ื“ื™ืจ ืื•ืชืŸ ื‘ืืžืฆืขื•ืช ื”ืชืฆื•ืจื” ื”ืงื•ืžืคื™ืœื˜ื™ืช. ืขื‘ื•ืจ ื”ื’ื“ืจื” ืžื—ื“ืฉ ื“ื™ื ืžื™ืช, ื™ื™ืชื›ืŸ ืฉื ืฆื˜ืจืš ืžื ื’ื ื•ืŸ ืœื”ืคืขืœื” ืžื—ื“ืฉ ืฉืœ ื—ืœืงื™ื ืžื”ืชื•ื›ื ื™ืช ืขื ืคืจืžื˜ืจื™ื ื—ื“ืฉื™ื, ื‘ื“ื•ืžื” ืœืื•ืคืŸ ืฉื‘ื• ืชื”ืœื™ื›ื™ ืžืขืจื›ืช ื”ื”ืคืขืœื” ืžื•ืคืขืœื™ื ืžื—ื“ืฉ. (ืœื“ืขืชื ื•, ืจืฆื•ื™ ืœื”ื™ืžื ืข ืžื”ื’ื“ืจื” ืžื—ื“ืฉ ื‘ื–ืžืŸ ืืžืช, ืฉื›ืŸ ื”ื“ื‘ืจ ืžื’ื“ื™ืœ ืืช ืžื•ืจื›ื‘ื•ืช ื”ืžืขืจื›ืช. ื‘ืžื™ื“ืช ื”ืืคืฉืจ, ืขื“ื™ืฃ ืœื”ืฉืชืžืฉ ื‘ื™ื›ื•ืœื•ืช ืžืขืจื›ืช ื”ื”ืคืขืœื” ื”ืกื˜ื ื“ืจื˜ื™ื•ืช ืœืฆื•ืจืš ื”ืคืขืœื” ืžื—ื“ืฉ ืฉืœ ืชื”ืœื™ื›ื™ื).

ื”ื™ื‘ื˜ ื—ืฉื•ื‘ ืื—ื“ ืฉืœ ืฉื™ืžื•ืฉ ื‘ืชืฆื•ืจื” ืกื˜ื˜ื™ืช ืฉื’ื•ืจื ืœืื ืฉื™ื ืœืฉืงื•ืœ ืชืฆื•ืจื” ืžื—ื“ืฉ ื“ื™ื ืžื™ืช ื”ื•ื ื”ื–ืžืŸ ืฉืœื•ืงื— ืœืžืขืจื›ืช ืœืืชื—ืœ ืžื—ื“ืฉ ืœืื—ืจ ืขื“ื›ื•ืŸ ืชืฆื•ืจื” (ื”ืฉื‘ืชื”). ืœืžืขืฉื”, ืื ื ืฆื˜ืจืš ืœื‘ืฆืข ืฉื™ื ื•ื™ื™ื ื‘ืชืฆื•ืจื” ื”ืกื˜ื˜ื™ืช, ื ืฆื˜ืจืš ืœื”ืคืขื™ืœ ืžื—ื“ืฉ ืืช ื”ืžืขืจื›ืช ื›ื“ื™ ืฉื”ืขืจื›ื™ื ื”ื—ื“ืฉื™ื ื™ื™ื›ื ืกื• ืœืชื•ืงืฃ. ื‘ืขื™ื™ืช ื–ืžืŸ ื”ื”ืฉื‘ืชื” ืžืฉืชื ื” ื‘ื—ื•ืžืจืชื” ืขื‘ื•ืจ ืžืขืจื›ื•ืช ืฉื•ื ื•ืช. ื‘ืžืงืจื™ื ืžืกื•ื™ืžื™ื, ืืชื” ื™ื›ื•ืœ ืœืชื–ืžืŸ ืืชื—ื•ืœ ืžื—ื“ืฉ ื‘ื–ืžืŸ ืฉื‘ื• ื”ืขื•ืžืก ืžื™ื ื™ืžืœื™. ืื ืืชื” ืฆืจื™ืš ืœืกืคืง ืฉื™ืจื•ืช ืจืฆื™ืฃ, ืืชื” ื™ื›ื•ืœ ืœื™ื™ืฉื ื ื™ืงื•ื– ื—ื™ื‘ื•ืจ AWS ELB. ื‘ืžืงื‘ื™ืœ, ื›ืืฉืจ ืื ื• ืฆืจื™ื›ื™ื ืœืืชื—ืœ ืืช ื”ืžืขืจื›ืช, ืื ื• ืžืคืขื™ืœื™ื ืžื•ืคืข ืžืงื‘ื™ืœ ืฉืœ ืžืขืจื›ืช ื–ื•, ืžืขื‘ื™ืจื™ื ืืœื™ื• ืืช ื”ืื™ื–ื•ืŸ ื•ืžื—ื›ื™ื ืœื”ืฉืœืžืช ื”ื—ื™ื‘ื•ืจื™ื ื”ื™ืฉื ื™ื. ืœืื—ืจ ืฉื›ืœ ื”ื—ื™ื‘ื•ืจื™ื ื”ื™ืฉื ื™ื ื”ืกืชื™ื™ืžื•, ืื ื• ืžื›ื‘ื™ื ืืช ื”ืžื•ืคืข ื”ื™ืฉืŸ ืฉืœ ื”ืžืขืจื›ืช.

ื”ื‘ื” ื ื‘ื—ืŸ ื›ืขืช ืืช ื”ื ื•ืฉื ืฉืœ ืื—ืกื•ืŸ ื”ืชืฆื•ืจื” ื‘ืชื•ืš ืื• ืžื—ื•ืฆื” ืœื• ื”ื—ืคืฅ. ืื ื ืื—ืกืŸ ืืช ื”ืชืฆื•ืจื” ื‘ืชื•ืš ื—ืคืฅ, ืื– ืœืคื—ื•ืช ื”ื™ื™ืชื” ืœื ื• ื”ื–ื“ืžื ื•ืช ืœืืžืช ืืช ื ื›ื•ื ื•ืช ื”ืชืฆื•ืจื” ื‘ืžื”ืœืš ื”ื”ืจื›ื‘ื” ืฉืœ ื”ื—ืคืฅ. ืื ื”ืชืฆื•ืจื” ื ืžืฆืืช ืžื—ื•ืฅ ืœืืจื˜ื™ืคืงื˜ ื”ื ืฉืœื˜, ืงืฉื” ืœืขืงื•ื‘ ืื—ืจ ืžื™ ื‘ื™ืฆืข ืฉื™ื ื•ื™ื™ื ื‘ืงื•ื‘ืฅ ื”ื–ื” ื•ืžื“ื•ืข. ื›ืžื” ื–ื” ื—ืฉื•ื‘? ืœื“ืขืชื ื•, ืขื‘ื•ืจ ืžืขืจื›ื•ืช ื™ื™ืฆื•ืจ ืจื‘ื•ืช ื—ืฉื•ื‘ ืฉืชื”ื™ื” ืชืฆื•ืจื” ื™ืฆื™ื‘ื” ื•ืื™ื›ื•ืชื™ืช.

ื”ื’ืจืกื” ืฉืœ ื—ืคืฅ ืžืืคืฉืจืช ืœืš ืœืงื‘ื•ืข ืžืชื™ ื”ื•ื ื ื•ืฆืจ, ืื™ืœื• ืขืจื›ื™ื ื”ื•ื ืžื›ื™ืœ, ืื™ืœื• ืคื•ื ืงืฆื™ื•ืช ืžื•ืคืขืœื•ืช/ืžื•ืฉื‘ืชื•ืช ื•ืžื™ ืื—ืจืื™ ืœื›ืœ ืฉื™ื ื•ื™ ื‘ืชืฆื•ืจื”. ื›ืžื•ื‘ืŸ, ืื—ืกื•ืŸ ื”ืชืฆื•ืจื” ื‘ืชื•ืš ื—ืคืฅ ื“ื•ืจืฉ ืงืฆืช ืžืืžืฅ, ืื– ืืชื” ืฆืจื™ืš ืœืงื‘ืœ ื”ื—ืœื˜ื” ืžื•ืฉื›ืœืช.

ื”ื™ืชืจื•ื ื•ืช ื•ื”ื—ืกืจื•ื ื•ืช

ืื ื™ ืจื•ืฆื” ืœื”ืชืขื›ื‘ ืขืœ ื”ื™ืชืจื•ื ื•ืช ื•ื”ื—ืกืจื•ื ื•ืช ืฉืœ ื”ื˜ื›ื ื•ืœื•ื’ื™ื” ื”ืžื•ืฆืขืช.

ื™ืชืจื•ื ื•ืช

ืœื”ืœืŸ ืจืฉื™ืžื” ืฉืœ ื”ืชื›ื•ื ื•ืช ื”ืขื™ืงืจื™ื•ืช ืฉืœ ืชืฆื•ืจืช ืžืขืจื›ืช ืžื‘ื•ื–ืจืช ืžื”ื•ื“ืจืช:

  1. ื‘ื“ื™ืงืช ืชืฆื•ืจื” ืกื˜ื˜ื™ืช. ืžืืคืฉืจ ืœืš ืœื”ื™ื•ืช ื‘ื˜ื•ื— ื‘ื›ืš
    ื”ืชืฆื•ืจื” ื ื›ื•ื ื”.
  2. ืฉืคืช ืชืฆื•ืจื” ืขืฉื™ืจื”. ื‘ื“ืจืš ื›ืœืœ, ืฉื™ื˜ื•ืช ืชืฆื•ืจื” ืื—ืจื•ืช ืžื•ื’ื‘ืœื•ืช ืœื”ื—ืœืคืช ืžืฉืชื ื™ ืžื—ืจื•ื–ืช ืœื›ืœ ื”ื™ื•ืชืจ. ื‘ืขืช ืฉื™ืžื•ืฉ ื‘-Scala, ืžื’ื•ื•ืŸ ืจื—ื‘ ืฉืœ ืชื›ื•ื ื•ืช ืฉืคื” ื–ืžื™ื ื•ืช ื›ื“ื™ ืœืฉืคืจ ืืช ื”ืชืฆื•ืจื” ืฉืœืš. ืœืžืฉืœ ืื ื—ื ื• ื™ื›ื•ืœื™ื ืœื”ืฉืชืžืฉ
    ืชื›ื•ื ื•ืช ืขื‘ื•ืจ ืขืจื›ื™ ื‘ืจื™ืจืช ืžื—ื“ืœ, ื‘ืืžืฆืขื•ืช ืื•ื‘ื™ื™ืงื˜ื™ื ืœืงื‘ืฅ ืคืจืžื˜ืจื™ื, ืื ื• ื™ื›ื•ืœื™ื ืœื”ืชื™ื™ื—ืก ืœ-vals ืฉื”ื•ื›ืจื–ื• ืจืง ืคืขื ืื—ืช (DRY) ื‘ื”ื™ืงืฃ ื”ืžืงื™ืฃ. ืืชื” ื™ื›ื•ืœ ืœื”ืคืขื™ืœ ื›ืœ ืฉื™ืขื•ืจ ื™ืฉื™ืจื•ืช ื‘ืชื•ืš ื”ืชืฆื•ืจื” (Seq, Map, ืฉื™ืขื•ืจื™ื ืžื•ืชืืžื™ื ืื™ืฉื™ืช).
  3. DSL. ืœ-Scala ื™ืฉ ืžืกืคืจ ืชื›ื•ื ื•ืช ืฉืคื” ื”ืžืงืœื•ืช ืขืœ ื™ืฆื™ืจืช DSL. ืืคืฉืจ ืœื ืฆืœ ืืช ื”ืชื›ื•ื ื•ืช ื”ืœืœื• ื•ืœื”ื˜ืžื™ืข ืฉืคืช ืงื•ื ืคื™ื’ื•ืจืฆื™ื” ื”ื ื•ื—ื” ื™ื•ืชืจ ืœืงื‘ื•ืฆืช ื”ื™ืขื“ ืฉืœ ื”ืžืฉืชืžืฉื™ื, ื›ืš ืฉื”ืงื•ื ืคื™ื’ื•ืจืฆื™ื” ืชื”ื™ื” ื ื™ืชื ืช ืœืงืจื™ืื” ืœืคื—ื•ืช ืขืœ ื™ื“ื™ ืžื•ืžื—ื™ ืชื—ื•ื. ืžื•ืžื—ื™ื ื™ื›ื•ืœื™ื, ืœืžืฉืœ, ืœื”ืฉืชืชืฃ ื‘ืชื”ืœื™ืš ืกืงื™ืจืช ื”ืชืฆื•ืจื”.
  4. ืฉืœืžื•ืช ื•ืกื ื›ืจื•ืŸ ื‘ื™ืŸ ืฆืžืชื™ื. ืื—ื“ ื”ื™ืชืจื•ื ื•ืช ืฉืœ ื”ืชืฆื•ืจื” ืฉืœ ืžืขืจื›ืช ืžื‘ื•ื–ืจืช ืฉืœืžื” ืžืื•ื—ืกื ืช ื‘ื ืงื•ื“ื” ืื—ืช ื”ื•ื ืฉื›ืœ ื”ืขืจื›ื™ื ืžื•ืฆื”ืจื™ื ื‘ื“ื™ื•ืง ืคืขื ืื—ืช ื•ืื– ื ืขืฉื” ื‘ื”ื ืฉื™ืžื•ืฉ ื—ื•ื–ืจ ื‘ื›ืœ ืžืงื•ื ื‘ื• ื”ื ื ื“ืจืฉื™ื. ืฉื™ืžื•ืฉ ื‘ืกื•ื’ื™ ืคื ื˜ื•ื ืœื”ื›ืจื–ื” ืขืœ ื™ืฆื™ืื•ืช ืžื‘ื˜ื™ื— ืฉื”ืฆืžืชื™ื ืžืฉืชืžืฉื™ื ื‘ืคืจื•ื˜ื•ืงื•ืœื™ื ืชื•ืืžื™ื ื‘ื›ืœ ืชืฆื•ืจื•ืช ื”ืžืขืจื›ืช ื”ื ื›ื•ื ื•ืช. ืชืœื•ืช ื—ื•ื‘ื” ืžืคื•ืจืฉืช ื‘ื™ืŸ ืฆืžืชื™ื ืžื‘ื˜ื™ื—ื” ืฉื›ืœ ื”ืฉื™ืจื•ืชื™ื ืžื—ื•ื‘ืจื™ื.
  5. ืฉื™ื ื•ื™ื™ื ื‘ืื™ื›ื•ืช ื’ื‘ื•ื”ื”. ื‘ื™ืฆื•ืข ืฉื™ื ื•ื™ื™ื ื‘ืชืฆื•ืจื” ื‘ืืžืฆืขื•ืช ืชื”ืœื™ืš ืคื™ืชื•ื— ืžืฉื•ืชืฃ ืžืืคืฉืจ ืœื”ื’ื™ืข ืœืชืงื ื™ ืื™ื›ื•ืช ื’ื‘ื•ื”ื™ื ื’ื ืœืชืฆื•ืจื”.
  6. ืขื“ื›ื•ืŸ ืชืฆื•ืจื” ื‘ื• ื–ืžื ื™ืช. ืคืจื™ืกืช ืžืขืจื›ืช ืื•ื˜ื•ืžื˜ื™ืช ืœืื—ืจ ืฉื™ื ื•ื™ื™ ืชืฆื•ืจื” ืžื‘ื˜ื™ื—ื” ืฉื›ืœ ื”ืฆืžืชื™ื ืžืขื•ื“ื›ื ื™ื.
  7. ืคื™ืฉื•ื˜ ื”ื™ื™ืฉื•ื. ื”ื™ื™ืฉื•ื ืื™ื ื• ื–ืงื•ืง ืœื ื™ืชื•ื—, ื‘ื“ื™ืงืช ืชืฆื•ืจื” ืื• ื˜ื™ืคื•ืœ ื‘ืขืจื›ื™ื ืฉื’ื•ื™ื™ื. ื–ื” ืžืงื˜ื™ืŸ ืืช ืžื•ืจื›ื‘ื•ืช ื”ื™ื™ืฉื•ื. (ื—ืœืง ืžืžื•ืจื›ื‘ื•ืช ื”ืชืฆื•ืจื” ืฉื ืฆืคืชื” ื‘ื“ื•ื’ืžื” ืฉืœื ื• ื”ื™ื ืœื ืชื›ื•ื ื” ืฉืœ ื”ืชืฆื•ืจื” ื”ืžื”ื•ื“ืจืช, ืืœื ืจืง ื”ื—ืœื˜ื” ืžื•ื“ืขืช ื”ืžื•ื ืขืช ืžื”ืจืฆื•ืŸ ืœืกืคืง ื‘ื˜ื™ื—ื•ืช ื˜ื™ืคื•ืกื™ืช ื’ื“ื•ืœื” ื™ื•ืชืจ.) ื“ื™ ืงืœ ืœื—ื–ื•ืจ ืœืชืฆื•ืจื” ื”ืจื’ื™ืœื” - ืคืฉื•ื˜ ื™ื™ืฉื ืืช ื”ื—ืกืจ ื—ืœืงื™ื. ืœื›ืŸ, ืืชื” ื™ื›ื•ืœ, ืœืžืฉืœ, ืœื”ืชื—ื™ืœ ืขื ืชืฆื•ืจื” ืžื”ื•ื“ืจืช, ืœื“ื—ื•ืช ืืช ื”ื™ื™ืฉื•ื ืฉืœ ื—ืœืงื™ื ืžื™ื•ืชืจื™ื ืขื“ ืœืžื•ืขื“ ืฉื‘ื• ื–ื” ื‘ืืžืช ื ื—ื•ืฅ.
  8. ืชืฆื•ืจื” ืžืื•ืžืชืช. ืžื›ื™ื•ื•ืŸ ืฉืฉื™ื ื•ื™ื™ ืชืฆื•ืจื” ืขื•ืงื‘ื™ื ืื—ืจ ื”ื’ื•ืจืœ ื”ืจื’ื™ืœ ืฉืœ ื›ืœ ืฉื™ื ื•ื™ ืื—ืจ, ื”ืคืœื˜ ืฉืื ื• ืžืงื‘ืœื™ื ื”ื•ื ื—ืคืฅ ืขื ื’ืจืกื” ื™ื™ื—ื•ื“ื™ืช. ื–ื” ืžืืคืฉืจ ืœื ื•, ืœืžืฉืœ, ืœื—ื–ื•ืจ ืœื’ืจืกื” ืงื•ื“ืžืช ืฉืœ ื”ืชืฆื•ืจื” ื‘ืžื™ื“ืช ื”ืฆื•ืจืš. ืื ื—ื ื• ื™ื›ื•ืœื™ื ืืคื™ืœื• ืœื”ืฉืชืžืฉ ื‘ืชืฆื•ืจื” ืžืœืคื ื™ ืฉื ื” ื•ื”ืžืขืจื›ืช ืชืขื‘ื•ื“ ื‘ื“ื™ื•ืง ืื•ืชื• ื”ื“ื‘ืจ. ืชืฆื•ืจื” ื™ืฆื™ื‘ื” ืžืฉืคืจืช ืืช ื”ื ื™ื‘ื•ื™ ื•ื”ืืžื™ื ื•ืช ืฉืœ ืžืขืจื›ืช ืžื‘ื•ื–ืจืช. ืžื›ื™ื•ื•ืŸ ืฉื”ืชืฆื•ืจื” ืงื‘ื•ืขื” ื‘ืฉืœื‘ ื”ื”ื™ื“ื•ืจ, ื“ื™ ืงืฉื” ืœื–ื™ื™ืฃ ืื•ืชื” ื‘ื™ื™ืฆื•ืจ.
  9. ืžื•ื“ื•ืœืจื™ื•ืช. ื”ืžืกื’ืจืช ื”ืžื•ืฆืขืช ื”ื™ื ืžื•ื“ื•ืœืจื™ืช ื•ื ื™ืชืŸ ืœืฉืœื‘ ืืช ื”ืžื•ื“ื•ืœื™ื ื‘ื“ืจื›ื™ื ืฉื•ื ื•ืช ืœื™ืฆื™ืจืช ืžืขืจื›ื•ืช ืฉื•ื ื•ืช. ื‘ืคืจื˜, ืืชื” ื™ื›ื•ืœ ืœื”ื’ื“ื™ืจ ืืช ื”ืžืขืจื›ืช ืœืคืขื•ืœ ืขืœ ืฆื•ืžืช ื‘ื•ื“ื“ ื‘ื”ืชื’ืœืžื•ืช ืื—ืช, ื•ืขืœ ืžืกืคืจ ืฆืžืชื™ื ื‘ืื—ืจ. ื ื™ืชืŸ ืœื™ืฆื•ืจ ืžืกืคืจ ืชืฆื•ืจื•ืช ืขื‘ื•ืจ ืžื•ืคืขื™ ื™ื™ืฆื•ืจ ืฉืœ ื”ืžืขืจื›ืช.
  10. ื‘ื“ื™ืงื”. ืขืœ ื™ื“ื™ ื”ื—ืœืคืช ืฉื™ืจื•ืชื™ื ื‘ื•ื“ื“ื™ื ื‘ืื•ื‘ื™ื™ืงื˜ื™ื ืžื“ื•ืžื™ื, ื ื™ืชืŸ ืœืงื‘ืœ ืžืกืคืจ ื’ืจืกืื•ืช ืฉืœ ื”ืžืขืจื›ืช ืฉื ื•ื—ื•ืช ืœื‘ื“ื™ืงื”.
  11. ื‘ื“ื™ืงืช ืื™ื ื˜ื’ืจืฆื™ื”. ืงื™ื•ื ืชืฆื•ืจื” ืื—ืช ืœื›ืœ ื”ืžืขืจื›ืช ื”ืžื‘ื•ื–ืจืช ืžืืคืฉืจืช ืœื”ืคืขื™ืœ ืืช ื›ืœ ื”ืจื›ื™ื‘ื™ื ื‘ืกื‘ื™ื‘ื” ืžื‘ื•ืงืจืช ื›ื—ืœืง ืžื‘ื“ื™ืงื•ืช ืื™ื ื˜ื’ืจืฆื™ื”. ืงืœ ืœื—ืงื•ืช, ืœืžืฉืœ, ืžืฆื‘ ืฉื‘ื• ืฆืžืชื™ื ืžืกื•ื™ืžื™ื ื”ื•ืคื›ื™ื ื ื’ื™ืฉื™ื.

ื—ืกืจื•ื ื•ืช ื•ืžื’ื‘ืœื•ืช

ืชืฆื•ืจื” ืžื”ื•ื“ืจืช ืฉื•ื ื” ืžื’ื™ืฉื•ืช ืชืฆื•ืจื” ืื—ืจื•ืช ื•ื™ื™ืชื›ืŸ ืฉืœื ืชืชืื™ื ืœื™ื™ืฉื•ืžื™ื ืžืกื•ื™ืžื™ื. ืœื”ืœืŸ ื›ืžื” ื—ืกืจื•ื ื•ืช:

  1. ืชืฆื•ืจื” ืกื˜ื˜ื™ืช. ืœืคืขืžื™ื ืืชื” ืฆืจื™ืš ืœืชืงืŸ ื‘ืžื”ื™ืจื•ืช ืืช ื”ืชืฆื•ืจื” ื‘ื™ื™ืฆื•ืจ, ืœืขืงื•ืฃ ืืช ื›ืœ ืžื ื’ื ื•ื ื™ ื”ื”ื’ื ื”. ืขื ื’ื™ืฉื” ื–ื• ื–ื” ื™ื›ื•ืœ ืœื”ื™ื•ืช ืงืฉื” ื™ื•ืชืจ. ืœื›ืœ ื”ืคื—ื•ืช, ืขื“ื™ื™ืŸ ื™ื™ื“ืจืฉื• ืงื•ืžืคื™ืœืฆื™ื” ื•ืคืจื™ืกื” ืื•ื˜ื•ืžื˜ื™ืช. ื–ื• ื’ื ืชื›ื•ื ื” ืฉื™ืžื•ืฉื™ืช ืฉืœ ื”ื’ื™ืฉื” ื•ื’ื ื—ื™ืกืจื•ืŸ ื‘ืžืงืจื™ื ืžืกื•ื™ืžื™ื.
  2. ื™ืฆื™ืจืช ืชืฆื•ืจื”. ื‘ืžืงืจื” ืฉืงื•ื‘ืฅ ื”ืชืฆื•ืจื” ื ื•ืฆืจ ืขืœ ื™ื“ื™ ื›ืœื™ ืื•ื˜ื•ืžื˜ื™, ื™ื™ืชื›ืŸ ืฉื™ื™ื“ืจืฉื• ืžืืžืฆื™ื ื ื•ืกืคื™ื ื›ื“ื™ ืœืฉืœื‘ ืืช ืกืงืจื™ืคื˜ ื”-build.
  3. ื›ืœื™ื. ื ื›ื•ืŸ ืœืขื›ืฉื™ื•, ื›ืœื™ ืขื–ืจ ื•ื˜ื›ื ื™ืงื•ืช ืฉื ื•ืขื“ื• ืœืขื‘ื•ื“ ืขื ืชืฆื•ืจื” ืžื‘ื•ืกืกื™ื ืขืœ ืงื‘ืฆื™ ื˜ืงืกื˜. ืœื ื›ืœ ื›ืœื™ ื”ืฉื™ืจื•ืช/ื˜ื›ื ื™ืงื•ืช ื›ืืœื” ื™ื”ื™ื• ื–ืžื™ื ื™ื ื‘ืชืฆื•ืจื” ืžื”ื•ื“ืจืช.
  4. ื ื“ืจืฉ ืฉื™ื ื•ื™ ืขืžื“ื•ืช. ืžืคืชื—ื™ื ื•-DevOps ืจื’ื™ืœื™ื ืœืงื‘ืฆื™ ื˜ืงืกื˜. ืขืฆื ื”ืจืขื™ื•ืŸ ืฉืœ ื”ื™ื“ื•ืจ ืฉืœ ืชืฆื•ืจื” ืขืฉื•ื™ ืœื”ื™ื•ืช ืžืขื˜ ื‘ืœืชื™ ืฆืคื•ื™ ื•ื—ืจื™ื’ ื•ืœื’ืจื•ื ืœื“ื—ื™ื™ื”.
  5. ื ื“ืจืฉ ืชื”ืœื™ืš ืคื™ืชื•ื— ื‘ืื™ื›ื•ืช ื’ื‘ื•ื”ื”. ืขืœ ืžื ืช ืœื”ืฉืชืžืฉ ื‘ื ื•ื—ื•ืช ื‘ืชืฆื•ืจืช ื”ืงื•ืžืคื™ืœืฆื™ื”, ื™ืฉ ืฆื•ืจืš ื‘ืื•ื˜ื•ืžืฆื™ื” ืžืœืื” ืฉืœ ืชื”ืœื™ืš ื”ื‘ื ื™ื™ื” ื•ื”ืคืจื™ืกื” ืฉืœ ื”ืืคืœื™ืงืฆื™ื” (CI/CD). ืื—ืจืช ื–ื” ื™ื”ื™ื” ื“ื™ ืœื ื ื•ื—.

ื”ื‘ื” ื ืชืขื›ื‘ ื’ื ืขืœ ืžืกืคืจ ืžื’ื‘ืœื•ืช ืฉืœ ื”ื“ื•ื’ืžื” ื”ื ื—ืฉื‘ืช ืฉืื™ื ืŸ ืงืฉื•ืจื•ืช ืœืจืขื™ื•ืŸ ืฉืœ ืชืฆื•ืจื” ืžื”ื•ื“ืจืช:

  1. ืื ื ืกืคืง ืžื™ื“ืข ืชืฆื•ืจื” ืžื™ื•ืชืจ ืฉืื™ื ื• ื‘ืฉื™ืžื•ืฉ ืขืœ ื™ื“ื™ ื”ืฆื•ืžืช, ืื– ื”ืžื”ื“ืจ ืœื ื™ืขื–ื•ืจ ืœื ื• ืœื–ื”ื•ืช ืืช ื”ืžื™ืžื•ืฉ ื”ื—ืกืจ. ื ื™ืชืŸ ืœืคืชื•ืจ ื‘ืขื™ื” ื–ื• ืขืœ ื™ื“ื™ ื ื˜ื™ืฉืช ื“ืคื•ืก ื”ืขื•ื’ื” ื•ืฉื™ืžื•ืฉ ื‘ืกื•ื’ื™ื ื ื•ืงืฉื™ื ื™ื•ืชืจ, ืœืžืฉืœ, HList ืื• ืกื•ื’ื™ ื ืชื•ื ื™ื ืืœื’ื‘ืจื™ื™ื (ืžื—ืœืงื•ืช ืžืงืจื”) ืœื™ื™ืฆื’ ืชืฆื•ืจื”.
  2. ื™ืฉื ืŸ ืฉื•ืจื•ืช ื‘ืงื•ื‘ืฅ ื”ืชืฆื•ืจื” ืฉืื™ื ืŸ ืงืฉื•ืจื•ืช ืœืชืฆื•ืจื” ืขืฆืžื”: (package, import,ื”ืฆื”ืจื•ืช ื—ืคืฆื™ื; override defืขื‘ื•ืจ ืคืจืžื˜ืจื™ื ืฉื™ืฉ ืœื”ื ืขืจื›ื™ ื‘ืจื™ืจืช ืžื—ื“ืœ). ื–ื” ื™ื›ื•ืœ ืœื”ื™ืžื ืข ื—ืœืงื™ืช ืื ืืชื” ืžื™ื™ืฉื DSL ืžืฉืœืš. ื‘ื ื•ืกืฃ, ืกื•ื’ื™ื ืื—ืจื™ื ืฉืœ ืชืฆื•ืจื” (ืœื“ื•ื’ืžื”, XML) ืžื˜ื™ืœื™ื ื’ื ื”ื’ื‘ืœื•ืช ืžืกื•ื™ืžื•ืช ืขืœ ืžื‘ื ื” ื”ืงื•ื‘ืฅ.
  3. ืœืžื˜ืจื•ืช ืคื•ืกื˜ ื–ื”, ืื™ื ื ื• ืฉื•ืงืœื™ื ื”ื’ื“ืจื” ืžื—ื“ืฉ ื“ื™ื ืžื™ืช ืฉืœ ืืฉื›ื•ืœ ืฉืœ ืฆืžืชื™ื ื“ื•ืžื™ื.

ืžืกืงื ื”

ื‘ืคื•ืกื˜ ื–ื”, ื‘ื“ืงื ื• ืืช ื”ืจืขื™ื•ืŸ ืฉืœ ื™ื™ืฆื•ื’ ืชืฆื•ืจื” ื‘ืงื•ื“ ื”ืžืงื•ืจ ื‘ืืžืฆืขื•ืช ื”ื™ื›ื•ืœื•ืช ื”ืžืชืงื“ืžื•ืช ืฉืœ ื”ืžืขืจื›ืช ืžืกื•ื’ Scala. ื’ื™ืฉื” ื–ื• ื™ื›ื•ืœื” ืœืฉืžืฉ ื‘ื™ื™ืฉื•ืžื™ื ืฉื•ื ื™ื ื›ืชื—ืœื™ืฃ ืœืฉื™ื˜ื•ืช ืชืฆื•ืจื” ืžืกื•ืจืชื™ื•ืช ื”ืžื‘ื•ืกืกื•ืช ืขืœ ืงื‘ืฆื™ xml ืื• ื˜ืงืกื˜. ืœืžืจื•ืช ืฉื”ื“ื•ื’ืžื” ืฉืœื ื• ืžื™ื•ืฉืžืช ื‘-Scala, ื ื™ืชืŸ ืœื”ืขื‘ื™ืจ ืืช ืื•ืชื ืจืขื™ื•ื ื•ืช ืœืฉืคื•ืช ืงื•ืžืคื™ืœืฆื™ื” ืื—ืจื•ืช (ื›ื’ื•ืŸ Kotlin, C#, Swift, ...). ืืชื” ื™ื›ื•ืœ ืœื ืกื•ืช ื’ื™ืฉื” ื–ื• ื‘ืื—ื“ ืžื”ืคืจื•ื™ืงื˜ื™ื ื”ื‘ืื™ื, ื•ืื ื–ื” ืœื ืขื•ื‘ื“, ืœืขื‘ื•ืจ ืœืงื•ื‘ืฅ ื”ื˜ืงืกื˜, ืœื”ื•ืกื™ืฃ ืืช ื”ื—ืœืงื™ื ื”ื—ืกืจื™ื.

ื‘ืื•ืคืŸ ื˜ื‘ืขื™, ืชืฆื•ืจื” ืžื”ื•ื“ืจืช ื“ื•ืจืฉืช ืชื”ืœื™ืš ืคื™ืชื•ื— ื‘ืื™ื›ื•ืช ื’ื‘ื•ื”ื”. ื‘ืชืžื•ืจื”, ืื™ื›ื•ืช ื’ื‘ื•ื”ื” ื•ืืžื™ื ื•ืช ืฉืœ ืชืฆื•ืจื•ืช ืžื•ื‘ื˜ื—ืช.

ื ื™ืชืŸ ืœื”ืจื—ื™ื‘ ืืช ื”ื’ื™ืฉื” ื”ื ื—ืฉื‘ืช:

  1. ืืชื” ื™ื›ื•ืœ ืœื”ืฉืชืžืฉ ื‘ืคืงื•ื“ื•ืช ืžืืงืจื• ื›ื“ื™ ืœื‘ืฆืข ื‘ื“ื™ืงื•ืช ื–ืžืŸ ืงื•ืžืคื™ืœืฆื™ื”.
  2. ืืชื” ื™ื›ื•ืœ ืœื™ื™ืฉื DSL ื›ื“ื™ ืœื”ืฆื™ื’ ืืช ื”ืชืฆื•ืจื” ื‘ืฆื•ืจื” ื ื’ื™ืฉื” ืœืžืฉืชืžืฉื™ ื”ืงืฆื”.
  3. ืืชื” ื™ื›ื•ืœ ืœื™ื™ืฉื ื ื™ื”ื•ืœ ืžืฉืื‘ื™ื ื“ื™ื ืžื™ ืขื ื”ืชืืžืช ืชืฆื•ืจื” ืื•ื˜ื•ืžื˜ื™ืช. ืœื“ื•ื’ืžื”, ืฉื™ื ื•ื™ ืžืกืคืจ ื”ืฆืžืชื™ื ื‘ืืฉื›ื•ืœ ืžื—ื™ื™ื‘ (1) ื›ืœ ืฆื•ืžืช ื™ืงื‘ืœ ืชืฆื•ืจื” ืžืขื˜ ืฉื•ื ื”; (2) ืžื ื”ืœ ื”ืืฉื›ื•ืœ ืงื™ื‘ืœ ืžื™ื“ืข ืขืœ ืฆืžืชื™ื ื—ื“ืฉื™ื.

ืชื•ื“ื•ืช

ืื ื™ ืจื•ืฆื” ืœื”ื•ื“ื•ืช ืœืื ื“ืจื™ื™ ืกืงืกื•ื ื•ื‘, ืคืื‘ืœ ืคื•ืคื•ื‘ ื•ืื ื˜ื•ืŸ ื ืงื™ื™ื‘ ืขืœ ื”ื‘ื™ืงื•ืจืช ื”ื‘ื•ื ื” ืฉืœื”ื ืขืœ ื˜ื™ื•ื˜ืช ื”ืžืืžืจ.

ืžืงื•ืจ: www.habr.com

ื”ื•ืกืคืช ืชื’ื•ื‘ื”