Olá. Na véspera do início do curso "Desenvolvedor Scala" , preparamos uma tradução útil para você.

2020 (I, II) , ZIO. 9 . ZIO 1.0, ZIO ZLayer.
, ZIO — . , /, , .
ZIO . 5 , , ZIO. : ZIO assert- TestClock.
1. ,
ZIO , JVM , . , .
(pollLoop) . , , . , - .
def pollLoop(running: Ref[Boolean],
consumer: Consumer
): UIO[Unit] =
running.get.flatMap {
case true => for {
_ <- pollAndHandle(consumer)
result <- pollLoop(running, consumer)
} yield result
case false => ZIO.unit
} , for-, , . For- flatMap, map. , for- . , — map — .
def pollLoop(running: Ref[Boolean],
consumer: Consumer
): UIO[Unit] =
running.get.flatMap {
case true =>
pollAndHandle(consumer)
.flatMap(_ => pollLoop(running, consumer))
.map(result => result)
case false => ZIO.unit
} Greyhound ZIO doWhile, , . , (pollOnce), doWhile:
pollOnce(running, consumer).doWhile(_ == true).forkDaemon , pollOnce UIO[boolean], , :
def pollOnce(running: Ref[Boolean],
consumer: Consumer
): UIO[Unit] =
running.get.flatMap {
case true => for {
_ <- pollAndHandle(consumer)
} yield true
case false => UIO(false)
}, - , .
2.
«» «» (. 2 2), , . :
def repeatedlyPublishQuote(stock: Stock) = {
publishQuote(stock).repeat(Schedule.fixed(1.second))
}
def publishQuote(stock: Stock) = {
println(s"getLatestQuote for $stock")
for {
quote <- grpcClient.getLatestQuote(stock)
_ <- sendToWebsocket(quote)
} yield ()
} ZIO, publishQuote, repeat repeatedlyPublishQuote. repeat .
— , ZIO. , - , .
, , , , console.putStrLn, for-, :
def publishQuote(stock: Stock) = {
val sendQuote = for {
_ <- console.putStrLn(s"getLatestQuote for $stock")
quote <- grpcClient.getLatestQuote(stock)
_ <- sendToWebsocket(quote)
} yield ()
sendQuote.catchAll(_ => UIO.unit)
}, catchAll for-, . .
3. TestClock assert-
, « », , . consumer, 1 , , .
- messageHandler , (assert), . , , .
. specs2, ScalaTest.
TestClock, ZIO, . TestClock , .
eventuallyZ:
def eventuallyZ[T](f: UIO[T])(predicate: T => Boolean): ZIO[Clock, Throwable, Unit] = {
f.repeat(Schedule.spaced(100.milliseconds) && Schedule.doUntil(predicate))
.timeoutFail(new RuntimeException)(4.seconds)
.unit
} Schedule ZIO 100 , - 4 .
. eventuallyZ Clock , , . Live Clock, , TestClock, eventuallyZ TestClock, , , TestClock.adjust .
ZIO provideSomeLayer:
def eventuallyZ[T](f: UIO[T])(predicate: T => Boolean): ZIO[Clock, Throwable, Unit] = {
f.repeat(Schedule.spaced(100.milliseconds) && Schedule.doUntil(predicate))
.timeoutFail(new RuntimeException)(4.seconds)
.provideSomeLayer(Clock.live)
.unit
} ZIO, eventuallyZ, Live Clock 100 . , TestClock.
4. assert- ZIO Test
: ZIO Test. : , :
object NumbersTest extends DefaultRunnableSpec {
override def spec =
testM("positive and even") {
checkAll(Gen.fromIterable(Seq(0, 2, 4, 6))) { number =>
assert(number)(isPositive)
assert(number % 2 == 0)(Assertion.isTrue)
}
}
} , , , , (, : Gen.anyInt.filter(_ > 0)). . isEven, assert . , , 0 .
+ positive and even after additionRan 1 test in 660 ms: 1 succeeded, 0 ignored, 0 failed , assert- &&:
assert(number)(isPositive) && assert(number % 2 == 0 (Assertion.isTrue):
Ran 1 test in 685 ms: 0 succeeded, 0 ignored, 1 failed
- positive and even after addition
Test failed after 1 iteration with input: 0
0 did not satisfy isGreaterThan(0)5. , Managed#Acquire
(fibers) ZIO — , / , ZIO.
, foreachPar.
. fork forkDaemon ( ). , ( ).
, ! ZManaged acquire release ( , ), , uninterruptible:
criticalEffect.uninterruptible Managed.acquire , «heart-beat» . Managed.release ( ).
object Server extends zio.ManagedApp {
def sendHeartBeat(): URIO[Console with Clock, Unit] =
console.putStrLn("heart-beat").repeat(Schedule.fixed(1.second)).ignore
override def run(args: List[String]): ZManaged[zio.ZEnv, Nothing, ExitCode] =
Managed
.make(sendHeartBeat().fork)(_.interrupt)
.map(_ => ExitCode(0))
}, fork , !
, ZIO, :
Managed.make(sendHeartBeat().fork.interruptible)(.interrupt):
sendHeartBeat().toManaged.forktoManaged_ , Managed.make.
!
:
ZIO, Twitter Medium. - , .