SlideShare a Scribd company logo
1 of 92
Download to read offline
ZIO Schedule John A. De Goes — @jdegoes - http://degoes.net Scala in the City
ZIO Schedule
Scala in the City, October 2018 - London, UK
John A. De Goes
@jdegoes - http://degoes.net
What is ZIO? Retries Repeats Schedule Composition
What is ZIO? Retries Repeats Schedule Composition
ZIO
ZIO lets you build high-performance,
type-safe, concurrent, asynchronous
applications that don’t leak resources,
and are easy to reason about
compositionally, test, and refactor.
github.com/scalaz/scalaz-zio
ZIO
What is ZIO? Retries Repeats Schedule Composition
def main: Unit = {
println("Hello, what is your name?")
val name = readLine()
println(s"Good morning, $name!")
}
Second-Class Effects
✗ Pass to functions
✗ Return from functions
✗ Store in data structures
✗ Async/sync/concurrency
✗ Async/sync resource-safety
What is ZIO? Retries Repeats Schedule Composition
def main: IO[IOException, Unit] = for {
_ <- putStrLn("Hello, what is your name?")
name <- getStrLn
_ <- putStrLn(s"Good morning, $name!")
} yield ()
First-Class Effects
✓ Pass to functions
✓ Return from functions
✓ Store in data structures
✓ Async/sync/concurrency
✓ Async/sync resource-safety
What is ZIO? Retries Repeats Schedule Composition
IO[E, A]
IO[E, A] is an immutable value that
describes an effectful program, which
may fail with a value of type E, or return
a value of type A.
What is ZIO? Retries Repeats Schedule Composition
ZIO IO
What is ZIO? Retries Repeats Schedule Composition
IO[Nothing, A]
Never fails
ZIO IO
What is ZIO? Retries Repeats Schedule Composition
IO[E, Nothing]
Never returns
ZIO IO
What is ZIO? Retries Repeats Schedule Composition
IO[Nothing, Nothing]
Never fails or returns
ZIO IO
for {
queue <- Queue.unbounded[String]
worker = queue.take.flatMap(putStrLn).forever
workers10k = List.fill(10000)(worker)
_ <- IO.forkAll(workers10k)
_ <- queue.offer("Chocolate!").forever.fork
} yield ()
Lightweight “Threads”
✓ Massive scalability over threads
✓ Non-blocking
✓ Safe concurrency
✓ Automatically interruptible
✓ Always resource-safe
✓ Powerful composition
What is ZIO? Retries Repeats Schedule Composition
for {
resp <- api.getUser(userId)
_ <- db.updateUser(userId, resp.profile)
_ <- promise.complete(())
} yield ()
What is ZIO? Retries Repeats Schedule Composition
✓ Massive scalability over threads
✓ Non-blocking
✓ Safe concurrency
✓ Automatically interruptible
✓ Always resource-safe
✓ Powerful composition
Asynchronicity
requests.parTraverse { request =>
for {
product <- findProduct(request.id)
update <- applyDiscount(product.id, discount)
_ <- db.updateProduct(product.id, update)
} yield product.id
}
What is ZIO? Retries Repeats Schedule Composition
✓ Massive scalability over threads
✓ Non-blocking
✓ Safe concurrency
✓ Automatically interruptible
✓ Always resource-safe
✓ Powerful composition
Concurrency
def fib(n: Int): IO[Nothing, Int] =
if (n <= 1) IO.now(n)
else fib(n-1).parWith(fib(n-2))(_ + _)
fib(Int.MaxValue).fork(_.interrupt)
What is ZIO? Retries Repeats Schedule Composition
✓ Massive scalability over threads
✓ Non-blocking
✓ Safe concurrency
✓ Automatically interruptible
✓ Always resource-safe
✓ Powerful composition
Interruption
openFile.bracket(closeFile(_)) { handle =>
def loop(ref: Ref[Chunk[Byte]]) =
for {
chunk <- handle.readChunk
<- ref.update(_ ++ chunk)
all <- if (handle.hasMore) loop(ref)
else ref.get
} yield all
Ref(Chunk.empty).flatMap(loop)
}
What is ZIO? Retries Repeats Schedule Composition
✓ Massive scalability over threads
✓ Non-blocking
✓ Safe concurrency
✓ Automatically interruptible
✓ Always resource-safe
✓ Powerful composition
Bracket
def webCrawler[E: Monoid, A: Monoid](seeds: Set[URL],
router: URL => Set[URL],
processor: (URL, String) => IO[E, A]):
IO[Nothing, Crawl[E, A]] = {
def loop(seeds: Set[URL], ref: Ref[CrawlState[E, A]]): IO[Nothing, Unit] =
ref.update(_ |+| CrawlState.visited(seeds)) *> IO.parTraverse(seeds)(
seed =>
getURL(seed).redeem(_ => IO.unit,
html => for {
visited <- ref.get.map(_.visited)
seeds <- IO.now(extractURLs(seed, html).toSet
.flatMap(router) -- visited)
crawl <- processor(seed, html).redeemPure(Crawl(_, mzero[A]),
Crawl(mzero[E], _))
_ <- ref.update(_ |+| CrawlState.crawled(crawl))
_ <- loop(seeds, ref)
} yield ())).void
Ref(mzero[CrawlState[E, A]]).flatMap(ref => loop(seeds, ref).map(_ =>
ref.get.map(_.crawl)))
}
What is ZIO? Retries Repeats Schedule Composition
✓ Massive scalability over threads
✓ Non-blocking
✓ Safe concurrency
✓ Automatically interruptible
✓ Always resource-safe
✓ Powerful composition
Composable
Retries
What is ZIO? Retries Repeats Schedule Composition
What is ZIO? Retries Repeats Schedule Composition
App Web API
What is ZIO? Retries Repeats Schedule Composition
App Web API
408
What is ZIO? Retries Repeats Schedule Composition
App Web API
408429
What is ZIO? Retries Repeats Schedule Composition
App Web API
408429
423
What is ZIO? Retries Repeats Schedule Composition
App Web API
408429
423
500
What is ZIO? Retries Repeats Schedule Composition
App Web API
408429
423
500 503
What is ZIO? Retries Repeats Schedule Composition
App Web API
408429
423
500 503
504
What is ZIO? Retries Repeats Schedule Composition
App Web API
408429
423
500 503
504
What is ZIO? Retries Repeats Schedule Composition
AppDatabase
Cache
Local
Storage
Cloud
Storage
Streaming Logs
Analytics
Web APIs
def networkRequest(): A = ???
def networkRequestWithRetries(max: Int, millis: Long): A = {
var i = 0
while (i < max) {
try {
return networkRequest()
}
catch {
case _ : Exception =>
i = i + 1
Thread.sleep(millis)
}
}
}
What is ZIO? Retries Repeats Schedule Composition
Retrying Synchronously
Repeats
What is ZIO? Retries Repeats Schedule Composition
What is ZIO? Retries Repeats Schedule Composition
App
Generate
Report
What is ZIO? Retries Repeats Schedule Composition
App
Generate
Report
Every
user
What is ZIO? Retries Repeats Schedule Composition
App
Generate
Report
Every
user
Every
day
What is ZIO? Retries Repeats Schedule Composition
App
Generate
Report
Every
user
Every
day
Every
account
What is ZIO? Retries Repeats Schedule Composition
App
Generate
Report
Every
user
Every
day
Every
account
Every
week
What is ZIO? Retries Repeats Schedule Composition
AppService
Heartbeat
Data
Retrieval
Remote
Uploading
Report
Generation
Log Rotation File Cleanup
User
Reminders
Garbage
Collection
What is ZIO? Retries Repeats Schedule Composition
def reportGen(): A = ???
def repeatedReportGen(max: Int, millis: Long): List[A] = {
var list = List.empty[A]
var i = 0
while (i < max) {
list = reportGen() :: list
Thread.sleep(millis)
i = i + 1
}
list
}
Repeating Synchronously
Schedule
What is ZIO? Retries Repeats Schedule Composition
What is ZIO? Retries Repeats Schedule Composition
ZIO SCHEDULE
Schedule[A, B]
Schedule[A, B] is an immutable
value that describes an effectful
schedule, which after consuming an A,
produces a B and decides to halt or
continue after some delay d.
What is ZIO? Retries Repeats Schedule Composition
ZIO SCHEDULE
Schedule[A, B]
A
B
B
Continue?
Continue after delay d
Halt immediately
What is ZIO? Retries Repeats Schedule Composition
Should I repeat a
program that failed
with an E?
Should I repeat a
program that
returned an A?
Retries Repeats
What is ZIO? Retries Repeats Schedule Composition
Retries Repeats
Schedule[E, B] Schedule[A, B]
Retry policy
Consumes errors of type E
Emits values of type B
Repeat policy
Consumes return values of type
A
Emits values of type B
What is ZIO? Retries Repeats Schedule Composition
Schedule.never : Schedule[Any, Nothing]
Zero Recurrences
Accepts any input
Never recurs, never emitting a value
What is ZIO? Retries Repeats Schedule Composition
Schedule.once : Schedule[Any, Unit]
One Recurrence
Accepts any input
Recurs once, emitting unit
What is ZIO? Retries Repeats Schedule Composition
Schedule.forever : Schedule[Any, Int]
Infinite Recurrences
Consumes any input
Recurs forever without delay, emitting the number of recurrences so far
What is ZIO? Retries Repeats Schedule Composition
Schedule.recurs(n: Int) : Schedule[Any, Int]
Fixed Recurrences
Accepts any input
Recurs the specified number of times, emitting number of recurrences so far
durationtask task
What is ZIO? Retries Repeats Schedule Composition
Schedule.spaced(d: Duration) : Schedule[Any, Int]
Spaced Recurrences
Accepts any input
Recurs forever with delay, emitting the number of recurrences so far
duration
task task
What is ZIO? Retries Repeats Schedule Composition
Schedule.fixed(d: Duration) : Schedule[Any, Int]
Fixed Recurrences
Accepts any input
Recurs forever with a delay, emitting number of recurrences so far
duration
What is ZIO? Retries Repeats Schedule Composition
Schedule.exponential(d: Duration, f: Double = 2.0) : Schedule[Any, Duration]
Exponential Recurrences
Accepts any input
Recurs forever with delay, emitting the current delay between steps
Scaling factor
Starting duration
What is ZIO? Retries Repeats Schedule Composition
Schedule.doWhile[A](f: A => Boolean): Schedule[A, A]
Conditional Recurrences
Accepts an A
Recurs while the predicate is true without delay, emitting the same A
Recurrence condition
What is ZIO? Retries Repeats Schedule Composition
Schedule.doUntil[A](f: A => Boolean): Schedule[A, A]
Conditional Recurrences
Accepts an A
Recurs until the predicate is true without delay, emitting the same A
Recurrence condition
What is ZIO? Retries Repeats Schedule Composition
Schedule.collect: Schedule[A, List[A]]
Collecting Recurrences
Recurs forever without delay, emitting a list of all consumed A’s
Consumes an A
What is ZIO? Retries Repeats Schedule Composition
Schedule.identity[A]: Schedule[A, A]
Identity Recurrences
Recurs forever without delay, emitting the same A
Consumes an A
What is ZIO? Retries Repeats Schedule Composition
Schedule.unfold[A](a: => A)(f: A => A): Schedule[Any, A]
Unfold Recurrences
Recurs forever without delay, emitting an A by unfolding the seed through repeated application
Consumes any value
What is ZIO? Retries Repeats Schedule Composition
Schedule.point[A](a: => A): Schedule[Any, A]
Constant Output
Recurs forever without delay, emitting a constant
Consumes any value
What is ZIO? Retries Repeats Schedule Composition
Schedule.lift[A, B](f: A => B): Schedule[A, B]
Function Output
Recurs forever without delay, emitting the function applied to the input
Consumes an A
What is ZIO? Retries Repeats Schedule Composition
Retries Repeats
val action: IO[E, A] = ???
val policy: Schedule[E, B] = ???
val retried: IO[E, A] =
action retry policy
val action: IO[E, A] = ???
val policy: Schedule[A, B] = ???
val repeated: IO[E, B] =
action repeat policy
What is ZIO? Retries Repeats Schedule Composition
Retries Repeats
val action: IO[E, A] = ???
val policy: Schedule[E, B] = ???
val orElse: (E, B) => IO[E2, A] = ???
val retried: IO[E2, A] =
action retryOrElse (policy, orElse)
val action: IO[E, A] = ???
val policy: Schedule[A, B] = ???
val orElse: (E, Option[B]) => IO[E2, B] = ???
val repeated: IO[E2, B] =
action repeatOrElse (policy, onError)
What is ZIO? Retries Repeats Schedule Composition
Retries Repeats
val action: IO[E, A] = ???
val policy: Schedule[E, B] = ???
val orElse: (E, B) => IO[E2, B] = ???
val retried: IO[E2, Either[B, A]] =
action retryOrElse0 (policy, orElse)
val action: IO[E, A] = ???
val policy: Schedule[A, B] = ???
val orElse: (E, Option[B]) => IO[E2, C] = ???
val repeated: IO[E2, Either[C, B]] =
action repeatOrElse0 (policy, onError)
Composition
What is ZIO? Retries Repeats Schedule Composition
What is ZIO? Retries Repeats Schedule Composition
def networkRequestWithRetries(factor: Float = 1.5f, init: Int = 1, cur: Int = 0)
(implicit as: ActorSystem): Future[String] = {
networkRequest().recoverWith {
case NetworkException =>
val next: Int =
if (cur == 0) init
else Math.ceil(cur * factor).toInt
after(next.milliseconds, as.scheduler, global, Future.successful(1)).flatMap { _ =>
networkRequestWithRetries(factor, init, next)
}
case t: Throwable => throw t
}
}
Future Retries*
* https://hackernoon.com/exponential-back-off-with-scala-futures-7426340d0069
What is ZIO? Retries Repeats Schedule Composition
def retry[F[_]: Timer: RaiseThrowable, O](
fo : F[O],
delay : FiniteDuration,
nextDelay : FiniteDuration => FiniteDuration,
maxAttempts : Int,
retriable : Throwable => Boolean): Stream[F, O] = ???
FS2 Retry
What is ZIO? Retries Repeats Schedule Composition
Monix Retry & Repeat
Retries Repeats
val task : Task[A] = ???
val retries: Int = ???
val retried1: Task[A] =
task onErrorRestart (retries)
val pred: Throwable => Boolean = ???
val retried2: Task[A] =
task onErrorRestartIf (pred)
// onErrorRestartLoop
val task: Task[A] = ???
val pred: A => Boolean = ???
val repeated: Task[A] =
task restartUntil (pred)
What is ZIO? Retries Repeats Schedule Composition
ZIO SCHEDULE
Monoid
append
zero
What is ZIO? Retries Repeats Schedule Composition
ZIO SCHEDULE
Monoid
append
zero
Applicative
map
point
ap
What is ZIO? Retries Repeats Schedule Composition
ZIO SCHEDULE
Monoid
append
zero
Applicative
map
point
ap
Category
id
compose
What is ZIO? Retries Repeats Schedule Composition
ZIO SCHEDULE
Monoid
append
zero
Applicative
map
point
ap
Category
id
compose
Profunctor
lmap
rmap
dimap
What is ZIO? Retries Repeats Schedule Composition
ZIO SCHEDULE
Monoid
append
zero
Applicative
map
point
ap
Category
id
compose
Profunctor
lmap
rmap
dimap
Strong
first
second
What is ZIO? Retries Repeats Schedule Composition
ZIO SCHEDULE
Monoid
append
zero
Applicative
map
point
ap
Category
id
compose
Profunctor
lmap
rmap
dimap
Strong
first
second
Choice
left
right
What is ZIO? Retries Repeats Schedule Composition
(s1 : Schedule[A, B]) && (s2 : Schedule[A, C]) : Schedule[A, (B, C)]
Intersection
s1 s2 s1 && s2
Continue : Boolean b1 b2 b1 && b2
Delay : Duration d1 d2 d1.max(d2)
Emit : (A, B) a b (a, b)
What is ZIO? Retries Repeats Schedule Composition
(s1 : Schedule[A, B]) || (s2 : Schedule[A, C]) : Schedule[A, (B, C)]
Union
s1 s2 s1 || s2
Continue : Boolean b1 b2 b1 || b2
Delay : Duration d1 d2 d1.min(d2)
Emit : (A, B) a b (a, b)
What is ZIO? Retries Repeats Schedule Composition
(s1 : Schedule[A, B]) andThen (s2 : Schedule[A, C]) : Schedule[A, Either[B, C]]
Sequence
A
A
B
C
s1
s2
s1 andThen s2A Either[B, C]
What is ZIO? Retries Repeats Schedule Composition
(s1 : Schedule[A, B]) >>> (s2 : Schedule[B, C]) : Schedule[A, C]
Compose
A
B
B
C
s1
s2
s1 >>> s2A C
What is ZIO? Retries Repeats Schedule Composition
(s1 : Schedule[A, B]).jittered : Schedule[A, B]
Jittering
A AB Bs1 s1’
Delays randomly
jittered
What is ZIO? Retries Repeats Schedule Composition
(s1 : Schedule[A, B]).collect : Schedule[A, List[B]]
Collecting
A AB List[C]s1 s1’
Emissions collected
What is ZIO? Retries Repeats Schedule Composition
(s1 : Schedule[A, B]).whileInput(f: A => Boolean) : Schedule[A, B]
Filtering By Input
A AB Bs1 s1’
Continues while/until f returns true
(s1 : Schedule[A, B]).untilInput(f: A => Boolean) : Schedule[A, B]
What is ZIO? Retries Repeats Schedule Composition
(s1 : Schedule[A, B]).whileOutput(f: B => Boolean) : Schedule[A, B]
Filtering By Output
A AB Bs1 s1’
Continues while/until f returns true
(s1 : Schedule[A, B]).untilOutput(f: B => Boolean) : Schedule[A, B]
What is ZIO? Retries Repeats Schedule Composition
(s1 : Schedule[A, B]).map(f: B => C) : Schedule[A, C]
Mapping
A AB Cs1 s1’
B mapped to C
What is ZIO? Retries Repeats Schedule Composition
(s1 : Schedule[A, B]) *> (s2 : Schedule[A, C]) : Schedule[A, C]
(s1 && s2).map(_._2)
Left / Right Ap
(s1 : Schedule[A, B]) <* (s2 : Schedule[A, C]) : Schedule[A, B]
(s1 && s2).map(_._1)
What is ZIO? Retries Repeats Schedule Composition
(s1 : Schedule[A, B]).logInput(f: A => IO[Nothing, Unit]) : Schedule[A, B]
Logging Inputs
A AB Bs1 s1’
Inputs logged to f
What is ZIO? Retries Repeats Schedule Composition
(s1 : Schedule[A, B]).logOutput(f: B => IO[Nothing, Unit]) : Schedule[A, B]
Logging Outputs
A AB Bs1 s1’
Outputs logged to f
What is ZIO? Retries Repeats Schedule Composition
Crafting a ZIO Schedule
Produce a jittered schedule that first does exponential spacing (starting from 10
milliseconds), but then after the spacing reaches 60 seconds, switches over to fixed
spacing of 60 seconds between recurrences, but will only do that for up to 100
times, and emits a list of the collected inputs.
What is ZIO? Retries Repeats Schedule Composition
Crafting a ZIO Schedule
Produce a jittered schedule that first does exponential spacing (starting from 10
milliseconds), but then after the spacing reaches 60 seconds, switches over to fixed
spacing of 60 seconds between recurrences, but will only do that for up to 100
times, and emits a list of the collected inputs.
What is ZIO? Retries Repeats Schedule Composition
Crafting a ZIO Schedule
Produce a jittered schedule that first does exponential spacing (starting from 10
milliseconds), but then after the spacing reaches 60 seconds, switches over to fixed
spacing of 60 seconds between recurrences, but will only do that for up to 100
times, and emits a list of the collected inputs.
Schedule.exponential(10.milliseconds)
What is ZIO? Retries Repeats Schedule Composition
Crafting a ZIO Schedule
Produce a jittered schedule that first does exponential spacing (starting from 10
milliseconds), but then after the spacing reaches 60 seconds, switches over to fixed
spacing of 60 seconds between recurrences, but will only do that for up to 100
times, and emits a list of the collected inputs.
(Schedule.exponential(10.milliseconds)
andThen ???)
What is ZIO? Retries Repeats Schedule Composition
Crafting a ZIO Schedule
Produce a jittered schedule that first does exponential spacing (starting from 10
milliseconds), but then after the spacing reaches 60 seconds, switches over to fixed
spacing of 60 seconds between recurrences, but will only do that for up to 100
times, and emits a list of the collected inputs.
(Schedule.exponential(10.milliseconds).whileOutput(_ < 60.seconds)
andThen ???)
What is ZIO? Retries Repeats Schedule Composition
Crafting a ZIO Schedule
Produce a jittered schedule that first does exponential spacing (starting from 10
milliseconds), but then after the spacing reaches 60 seconds, switches over to fixed
spacing of 60 seconds between recurrences, but will only do that for up to 100
times, and emits a list of the collected inputs.
(Schedule.exponential(10.milliseconds).whileOutput(_ < 60.seconds)
andThen
Schedule.fixed(60.seconds))
What is ZIO? Retries Repeats Schedule Composition
Crafting a ZIO Schedule
Produce a jittered schedule that first does exponential spacing (starting from 10
milliseconds), but then after the spacing reaches 60 seconds, switches over to fixed
spacing of 60 seconds between recurrences, but will only do that for up to 100
times, and emits a list of the collected inputs.
(Schedule.exponential(10.milliseconds).whileOutput(_ < 60.seconds)
andThen
(Schedule.fixed(60.seconds) && Schedule.recurs(100))
What is ZIO? Retries Repeats Schedule Composition
Crafting a ZIO Schedule
Produce a jittered schedule that first does exponential spacing (starting from 10
milliseconds), but then after the spacing reaches 60 seconds, switches over to fixed
spacing of 60 seconds between recurrences, but will only do that for up to 100
times, and emits a list of the collected inputs.
(Schedule.exponential(10.milliseconds).whileOutput(_ < 60.seconds)
andThen
(Schedule.fixed(60.seconds) && Schedule.recurs(100)).jittered
What is ZIO? Retries Repeats Schedule Composition
Crafting a ZIO Schedule
Produce a jittered schedule that first does exponential spacing (starting from 10
milliseconds), but then after the spacing reaches 60 seconds, switches over to fixed
spacing of 60 seconds between recurrences, but will only do that for up to 100
times, and emits a list of the collected inputs.
(Schedule.exponential(10.milliseconds).whileOutput(_ < 60.seconds)
andThen
(Schedule.fixed(60.seconds) && Schedule.recurs(100)).jittered
*> Schedule.identity[A].collect
What is ZIO? Retries Repeats Schedule Composition
Crafting a ZIO Schedule
Produce a jittered schedule that first does exponential spacing (starting from 10
milliseconds), but then after the spacing reaches 60 seconds, switches over to fixed
spacing of 60 seconds between recurrences, but will only do that for up to 100
times, and emits a list of the collected inputs.
def customSchedule[A]: Schedule[A, List[A]] = {
import Schedule._
(exponential(10.millis).whileOutput(_ < 60.secs) andThen
(fixed(60.secs) && recurs(100)).jittered *> identity[A].collect
}
Github
https://github.com/scalaz/scalaz-zio
Microsite
https://scalaz.github.io/scalaz-zio/
ZIO Chat
https://gitter.im/scalaz/scalaz-zio/
Scalaz Chat
https://gitter.im/scalaz/scalaz/
That’s A Wrap!
Functional Scala by John A. De Goes
Local Remote Date
London London Time Oct 21 - 23
Paris Paris Time Oct 25 - 27
SF / SV Pacific Coast Time Nov 18 - 21
That’s A Wrap!
THANK YOU!
@jdegoes - http://degoes.net
That’s A Wrap!

More Related Content

What's hot

Pynqでカメラ画像をリアルタイムfastx コーナー検出
Pynqでカメラ画像をリアルタイムfastx コーナー検出Pynqでカメラ画像をリアルタイムfastx コーナー検出
Pynqでカメラ画像をリアルタイムfastx コーナー検出marsee101
 
How shit works: the CPU
How shit works: the CPUHow shit works: the CPU
How shit works: the CPUTomer Gabel
 
Address/Thread/Memory Sanitizer
Address/Thread/Memory SanitizerAddress/Thread/Memory Sanitizer
Address/Thread/Memory SanitizerPlatonov Sergey
 
Analysing in depth work manager
Analysing in depth work managerAnalysing in depth work manager
Analysing in depth work managerbhatnagar.gaurav83
 
Boundary Conditions in OpenFOAM
Boundary Conditions in OpenFOAMBoundary Conditions in OpenFOAM
Boundary Conditions in OpenFOAMFumiya Nozaki
 
Pharo 10 and beyond
 Pharo 10 and beyond Pharo 10 and beyond
Pharo 10 and beyondESUG
 
BoostAsioで可読性を求めるのは間違っているだろうか
BoostAsioで可読性を求めるのは間違っているだろうかBoostAsioで可読性を求めるのは間違っているだろうか
BoostAsioで可読性を求めるのは間違っているだろうかYuki Miyatake
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modelingMario Fusco
 
One Monad to Rule Them All
One Monad to Rule Them AllOne Monad to Rule Them All
One Monad to Rule Them AllJohn De Goes
 
코틀린 멀티플랫폼, 미지와의 조우
코틀린 멀티플랫폼, 미지와의 조우코틀린 멀티플랫폼, 미지와의 조우
코틀린 멀티플랫폼, 미지와의 조우Arawn Park
 
Just-In-Time Compiler in PHP 8
Just-In-Time Compiler in PHP 8Just-In-Time Compiler in PHP 8
Just-In-Time Compiler in PHP 8Nikita Popov
 
非同期処理の基礎
非同期処理の基礎非同期処理の基礎
非同期処理の基礎信之 岩永
 

What's hot (20)

llvm入門
llvm入門llvm入門
llvm入門
 
Pynqでカメラ画像をリアルタイムfastx コーナー検出
Pynqでカメラ画像をリアルタイムfastx コーナー検出Pynqでカメラ画像をリアルタイムfastx コーナー検出
Pynqでカメラ画像をリアルタイムfastx コーナー検出
 
How shit works: the CPU
How shit works: the CPUHow shit works: the CPU
How shit works: the CPU
 
Clean coding-practices
Clean coding-practicesClean coding-practices
Clean coding-practices
 
Address/Thread/Memory Sanitizer
Address/Thread/Memory SanitizerAddress/Thread/Memory Sanitizer
Address/Thread/Memory Sanitizer
 
Analysing in depth work manager
Analysing in depth work managerAnalysing in depth work manager
Analysing in depth work manager
 
Lazy java
Lazy javaLazy java
Lazy java
 
Boundary Conditions in OpenFOAM
Boundary Conditions in OpenFOAMBoundary Conditions in OpenFOAM
Boundary Conditions in OpenFOAM
 
Pharo 10 and beyond
 Pharo 10 and beyond Pharo 10 and beyond
Pharo 10 and beyond
 
BoostAsioで可読性を求めるのは間違っているだろうか
BoostAsioで可読性を求めるのは間違っているだろうかBoostAsioで可読性を求めるのは間違っているだろうか
BoostAsioで可読性を求めるのは間違っているだろうか
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
 
Introduction to Linux Drivers
Introduction to Linux DriversIntroduction to Linux Drivers
Introduction to Linux Drivers
 
GDB Rocks!
GDB Rocks!GDB Rocks!
GDB Rocks!
 
C++ マルチスレッド 入門
C++ マルチスレッド 入門C++ マルチスレッド 入門
C++ マルチスレッド 入門
 
Interpreter, Compiler, JIT from scratch
Interpreter, Compiler, JIT from scratchInterpreter, Compiler, JIT from scratch
Interpreter, Compiler, JIT from scratch
 
USB Drivers
USB DriversUSB Drivers
USB Drivers
 
One Monad to Rule Them All
One Monad to Rule Them AllOne Monad to Rule Them All
One Monad to Rule Them All
 
코틀린 멀티플랫폼, 미지와의 조우
코틀린 멀티플랫폼, 미지와의 조우코틀린 멀티플랫폼, 미지와의 조우
코틀린 멀티플랫폼, 미지와의 조우
 
Just-In-Time Compiler in PHP 8
Just-In-Time Compiler in PHP 8Just-In-Time Compiler in PHP 8
Just-In-Time Compiler in PHP 8
 
非同期処理の基礎
非同期処理の基礎非同期処理の基礎
非同期処理の基礎
 

Similar to ZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional Programming

Scala, Functional Programming and Team Productivity
Scala, Functional Programming and Team ProductivityScala, Functional Programming and Team Productivity
Scala, Functional Programming and Team Productivity7mind
 
function* - ES6, generators, and all that (JSRomandie meetup, February 2014)
function* - ES6, generators, and all that (JSRomandie meetup, February 2014)function* - ES6, generators, and all that (JSRomandie meetup, February 2014)
function* - ES6, generators, and all that (JSRomandie meetup, February 2014)Igalia
 
The Design of the Scalaz 8 Effect System
The Design of the Scalaz 8 Effect SystemThe Design of the Scalaz 8 Effect System
The Design of the Scalaz 8 Effect SystemJohn De Goes
 
Escape from Mars
Escape from MarsEscape from Mars
Escape from MarsJorge Ortiz
 
Reusando componentes Zope fuera de Zope
Reusando componentes Zope fuera de ZopeReusando componentes Zope fuera de Zope
Reusando componentes Zope fuera de Zopementtes
 
Neal Gafter Java Evolution
Neal Gafter Java EvolutionNeal Gafter Java Evolution
Neal Gafter Java Evolutiondeimos
 
Getting property based testing to work after struggling for 3 years
Getting property based testing to work after struggling for 3 yearsGetting property based testing to work after struggling for 3 years
Getting property based testing to work after struggling for 3 yearsSaurabh Nanda
 
Python, async web frameworks, and MongoDB
Python, async web frameworks, and MongoDBPython, async web frameworks, and MongoDB
Python, async web frameworks, and MongoDBemptysquare
 
Phl mongo-philly-tornado-2011
Phl mongo-philly-tornado-2011Phl mongo-philly-tornado-2011
Phl mongo-philly-tornado-2011hangxin1940
 
Clojure - A new Lisp
Clojure - A new LispClojure - A new Lisp
Clojure - A new Lispelliando dias
 
Applied MyEclipse and JUnit to do Hibernate Code Gen and Testing
Applied MyEclipse and JUnit to do Hibernate Code Gen and TestingApplied MyEclipse and JUnit to do Hibernate Code Gen and Testing
Applied MyEclipse and JUnit to do Hibernate Code Gen and TestingGuo Albert
 
Asynchronous web apps with the Play Framework 2.0
Asynchronous web apps with the Play Framework 2.0Asynchronous web apps with the Play Framework 2.0
Asynchronous web apps with the Play Framework 2.0Oscar Renalias
 

Similar to ZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional Programming (20)

ZIO Queue
ZIO QueueZIO Queue
ZIO Queue
 
Scala, Functional Programming and Team Productivity
Scala, Functional Programming and Team ProductivityScala, Functional Programming and Team Productivity
Scala, Functional Programming and Team Productivity
 
Ray tracing with ZIO-ZLayer
Ray tracing with ZIO-ZLayerRay tracing with ZIO-ZLayer
Ray tracing with ZIO-ZLayer
 
function* - ES6, generators, and all that (JSRomandie meetup, February 2014)
function* - ES6, generators, and all that (JSRomandie meetup, February 2014)function* - ES6, generators, and all that (JSRomandie meetup, February 2014)
function* - ES6, generators, and all that (JSRomandie meetup, February 2014)
 
Berlin meetup
Berlin meetupBerlin meetup
Berlin meetup
 
The Design of the Scalaz 8 Effect System
The Design of the Scalaz 8 Effect SystemThe Design of the Scalaz 8 Effect System
The Design of the Scalaz 8 Effect System
 
Fiber supervision in ZIO
Fiber supervision in ZIOFiber supervision in ZIO
Fiber supervision in ZIO
 
Escape from Mars
Escape from MarsEscape from Mars
Escape from Mars
 
Reusando componentes Zope fuera de Zope
Reusando componentes Zope fuera de ZopeReusando componentes Zope fuera de Zope
Reusando componentes Zope fuera de Zope
 
Zio from Home
Zio from Home Zio from Home
Zio from Home
 
React native
React nativeReact native
React native
 
Intro to PSGI and Plack
Intro to PSGI and PlackIntro to PSGI and Plack
Intro to PSGI and Plack
 
Neal Gafter Java Evolution
Neal Gafter Java EvolutionNeal Gafter Java Evolution
Neal Gafter Java Evolution
 
Getting property based testing to work after struggling for 3 years
Getting property based testing to work after struggling for 3 yearsGetting property based testing to work after struggling for 3 years
Getting property based testing to work after struggling for 3 years
 
Python, async web frameworks, and MongoDB
Python, async web frameworks, and MongoDBPython, async web frameworks, and MongoDB
Python, async web frameworks, and MongoDB
 
Clojure And Swing
Clojure And SwingClojure And Swing
Clojure And Swing
 
Phl mongo-philly-tornado-2011
Phl mongo-philly-tornado-2011Phl mongo-philly-tornado-2011
Phl mongo-philly-tornado-2011
 
Clojure - A new Lisp
Clojure - A new LispClojure - A new Lisp
Clojure - A new Lisp
 
Applied MyEclipse and JUnit to do Hibernate Code Gen and Testing
Applied MyEclipse and JUnit to do Hibernate Code Gen and TestingApplied MyEclipse and JUnit to do Hibernate Code Gen and Testing
Applied MyEclipse and JUnit to do Hibernate Code Gen and Testing
 
Asynchronous web apps with the Play Framework 2.0
Asynchronous web apps with the Play Framework 2.0Asynchronous web apps with the Play Framework 2.0
Asynchronous web apps with the Play Framework 2.0
 

More from John De Goes

Error Management: Future vs ZIO
Error Management: Future vs ZIOError Management: Future vs ZIO
Error Management: Future vs ZIOJohn De Goes
 
Atomically { Delete Your Actors }
Atomically { Delete Your Actors }Atomically { Delete Your Actors }
Atomically { Delete Your Actors }John De Goes
 
The Death of Final Tagless
The Death of Final TaglessThe Death of Final Tagless
The Death of Final TaglessJohn De Goes
 
Scalaz Stream: Rebirth
Scalaz Stream: RebirthScalaz Stream: Rebirth
Scalaz Stream: RebirthJohn De Goes
 
Scalaz Stream: Rebirth
Scalaz Stream: RebirthScalaz Stream: Rebirth
Scalaz Stream: RebirthJohn De Goes
 
Blazing Fast, Pure Effects without Monads — LambdaConf 2018
Blazing Fast, Pure Effects without Monads — LambdaConf 2018Blazing Fast, Pure Effects without Monads — LambdaConf 2018
Blazing Fast, Pure Effects without Monads — LambdaConf 2018John De Goes
 
Scalaz 8: A Whole New Game
Scalaz 8: A Whole New GameScalaz 8: A Whole New Game
Scalaz 8: A Whole New GameJohn De Goes
 
Scalaz 8 vs Akka Actors
Scalaz 8 vs Akka ActorsScalaz 8 vs Akka Actors
Scalaz 8 vs Akka ActorsJohn De Goes
 
Orthogonal Functional Architecture
Orthogonal Functional ArchitectureOrthogonal Functional Architecture
Orthogonal Functional ArchitectureJohn De Goes
 
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & AnalyticsQuark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & AnalyticsJohn De Goes
 
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
 
Streams for (Co)Free!
Streams for (Co)Free!Streams for (Co)Free!
Streams for (Co)Free!John De Goes
 
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...John De Goes
 
Halogen: Past, Present, and Future
Halogen: Past, Present, and FutureHalogen: Past, Present, and Future
Halogen: Past, Present, and FutureJohn De Goes
 
All Aboard The Scala-to-PureScript Express!
All Aboard The Scala-to-PureScript Express!All Aboard The Scala-to-PureScript Express!
All Aboard The Scala-to-PureScript Express!John De Goes
 
Getting Started with PureScript
Getting Started with PureScriptGetting Started with PureScript
Getting Started with PureScriptJohn De Goes
 
SlamData - How MongoDB Is Powering a Revolution in Visual Analytics
SlamData - How MongoDB Is Powering a Revolution in Visual AnalyticsSlamData - How MongoDB Is Powering a Revolution in Visual Analytics
SlamData - How MongoDB Is Powering a Revolution in Visual AnalyticsJohn De Goes
 
The Next Great Functional Programming Language
The Next Great Functional Programming LanguageThe Next Great Functional Programming Language
The Next Great Functional Programming LanguageJohn De Goes
 
The Dark Side of NoSQL
The Dark Side of NoSQLThe Dark Side of NoSQL
The Dark Side of NoSQLJohn De Goes
 

More from John De Goes (20)

Error Management: Future vs ZIO
Error Management: Future vs ZIOError Management: Future vs ZIO
Error Management: Future vs ZIO
 
Atomically { Delete Your Actors }
Atomically { Delete Your Actors }Atomically { Delete Your Actors }
Atomically { Delete Your Actors }
 
The Death of Final Tagless
The Death of Final TaglessThe Death of Final Tagless
The Death of Final Tagless
 
Scalaz Stream: Rebirth
Scalaz Stream: RebirthScalaz Stream: Rebirth
Scalaz Stream: Rebirth
 
Scalaz Stream: Rebirth
Scalaz Stream: RebirthScalaz Stream: Rebirth
Scalaz Stream: Rebirth
 
Blazing Fast, Pure Effects without Monads — LambdaConf 2018
Blazing Fast, Pure Effects without Monads — LambdaConf 2018Blazing Fast, Pure Effects without Monads — LambdaConf 2018
Blazing Fast, Pure Effects without Monads — LambdaConf 2018
 
Scalaz 8: A Whole New Game
Scalaz 8: A Whole New GameScalaz 8: A Whole New Game
Scalaz 8: A Whole New Game
 
Scalaz 8 vs Akka Actors
Scalaz 8 vs Akka ActorsScalaz 8 vs Akka Actors
Scalaz 8 vs Akka Actors
 
Orthogonal Functional Architecture
Orthogonal Functional ArchitectureOrthogonal Functional Architecture
Orthogonal Functional Architecture
 
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & AnalyticsQuark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
 
Post-Free: Life After Free Monads
Post-Free: Life After Free MonadsPost-Free: Life After Free Monads
Post-Free: Life After Free Monads
 
Streams for (Co)Free!
Streams for (Co)Free!Streams for (Co)Free!
Streams for (Co)Free!
 
MTL Versus Free
MTL Versus FreeMTL Versus Free
MTL Versus Free
 
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
 
Halogen: Past, Present, and Future
Halogen: Past, Present, and FutureHalogen: Past, Present, and Future
Halogen: Past, Present, and Future
 
All Aboard The Scala-to-PureScript Express!
All Aboard The Scala-to-PureScript Express!All Aboard The Scala-to-PureScript Express!
All Aboard The Scala-to-PureScript Express!
 
Getting Started with PureScript
Getting Started with PureScriptGetting Started with PureScript
Getting Started with PureScript
 
SlamData - How MongoDB Is Powering a Revolution in Visual Analytics
SlamData - How MongoDB Is Powering a Revolution in Visual AnalyticsSlamData - How MongoDB Is Powering a Revolution in Visual Analytics
SlamData - How MongoDB Is Powering a Revolution in Visual Analytics
 
The Next Great Functional Programming Language
The Next Great Functional Programming LanguageThe Next Great Functional Programming Language
The Next Great Functional Programming Language
 
The Dark Side of NoSQL
The Dark Side of NoSQLThe Dark Side of NoSQL
The Dark Side of NoSQL
 

Recently uploaded

Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DaySri Ambati
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 

Recently uploaded (20)

Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 

ZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional Programming

  • 1. ZIO Schedule John A. De Goes — @jdegoes - http://degoes.net Scala in the City ZIO Schedule Scala in the City, October 2018 - London, UK John A. De Goes @jdegoes - http://degoes.net
  • 2. What is ZIO? Retries Repeats Schedule Composition
  • 3. What is ZIO? Retries Repeats Schedule Composition ZIO ZIO lets you build high-performance, type-safe, concurrent, asynchronous applications that don’t leak resources, and are easy to reason about compositionally, test, and refactor.
  • 4. github.com/scalaz/scalaz-zio ZIO What is ZIO? Retries Repeats Schedule Composition
  • 5. def main: Unit = { println("Hello, what is your name?") val name = readLine() println(s"Good morning, $name!") } Second-Class Effects ✗ Pass to functions ✗ Return from functions ✗ Store in data structures ✗ Async/sync/concurrency ✗ Async/sync resource-safety What is ZIO? Retries Repeats Schedule Composition
  • 6. def main: IO[IOException, Unit] = for { _ <- putStrLn("Hello, what is your name?") name <- getStrLn _ <- putStrLn(s"Good morning, $name!") } yield () First-Class Effects ✓ Pass to functions ✓ Return from functions ✓ Store in data structures ✓ Async/sync/concurrency ✓ Async/sync resource-safety What is ZIO? Retries Repeats Schedule Composition
  • 7. IO[E, A] IO[E, A] is an immutable value that describes an effectful program, which may fail with a value of type E, or return a value of type A. What is ZIO? Retries Repeats Schedule Composition ZIO IO
  • 8. What is ZIO? Retries Repeats Schedule Composition IO[Nothing, A] Never fails ZIO IO
  • 9. What is ZIO? Retries Repeats Schedule Composition IO[E, Nothing] Never returns ZIO IO
  • 10. What is ZIO? Retries Repeats Schedule Composition IO[Nothing, Nothing] Never fails or returns ZIO IO
  • 11. for { queue <- Queue.unbounded[String] worker = queue.take.flatMap(putStrLn).forever workers10k = List.fill(10000)(worker) _ <- IO.forkAll(workers10k) _ <- queue.offer("Chocolate!").forever.fork } yield () Lightweight “Threads” ✓ Massive scalability over threads ✓ Non-blocking ✓ Safe concurrency ✓ Automatically interruptible ✓ Always resource-safe ✓ Powerful composition What is ZIO? Retries Repeats Schedule Composition
  • 12. for { resp <- api.getUser(userId) _ <- db.updateUser(userId, resp.profile) _ <- promise.complete(()) } yield () What is ZIO? Retries Repeats Schedule Composition ✓ Massive scalability over threads ✓ Non-blocking ✓ Safe concurrency ✓ Automatically interruptible ✓ Always resource-safe ✓ Powerful composition Asynchronicity
  • 13. requests.parTraverse { request => for { product <- findProduct(request.id) update <- applyDiscount(product.id, discount) _ <- db.updateProduct(product.id, update) } yield product.id } What is ZIO? Retries Repeats Schedule Composition ✓ Massive scalability over threads ✓ Non-blocking ✓ Safe concurrency ✓ Automatically interruptible ✓ Always resource-safe ✓ Powerful composition Concurrency
  • 14. def fib(n: Int): IO[Nothing, Int] = if (n <= 1) IO.now(n) else fib(n-1).parWith(fib(n-2))(_ + _) fib(Int.MaxValue).fork(_.interrupt) What is ZIO? Retries Repeats Schedule Composition ✓ Massive scalability over threads ✓ Non-blocking ✓ Safe concurrency ✓ Automatically interruptible ✓ Always resource-safe ✓ Powerful composition Interruption
  • 15. openFile.bracket(closeFile(_)) { handle => def loop(ref: Ref[Chunk[Byte]]) = for { chunk <- handle.readChunk <- ref.update(_ ++ chunk) all <- if (handle.hasMore) loop(ref) else ref.get } yield all Ref(Chunk.empty).flatMap(loop) } What is ZIO? Retries Repeats Schedule Composition ✓ Massive scalability over threads ✓ Non-blocking ✓ Safe concurrency ✓ Automatically interruptible ✓ Always resource-safe ✓ Powerful composition Bracket
  • 16. def webCrawler[E: Monoid, A: Monoid](seeds: Set[URL], router: URL => Set[URL], processor: (URL, String) => IO[E, A]): IO[Nothing, Crawl[E, A]] = { def loop(seeds: Set[URL], ref: Ref[CrawlState[E, A]]): IO[Nothing, Unit] = ref.update(_ |+| CrawlState.visited(seeds)) *> IO.parTraverse(seeds)( seed => getURL(seed).redeem(_ => IO.unit, html => for { visited <- ref.get.map(_.visited) seeds <- IO.now(extractURLs(seed, html).toSet .flatMap(router) -- visited) crawl <- processor(seed, html).redeemPure(Crawl(_, mzero[A]), Crawl(mzero[E], _)) _ <- ref.update(_ |+| CrawlState.crawled(crawl)) _ <- loop(seeds, ref) } yield ())).void Ref(mzero[CrawlState[E, A]]).flatMap(ref => loop(seeds, ref).map(_ => ref.get.map(_.crawl))) } What is ZIO? Retries Repeats Schedule Composition ✓ Massive scalability over threads ✓ Non-blocking ✓ Safe concurrency ✓ Automatically interruptible ✓ Always resource-safe ✓ Powerful composition Composable
  • 17. Retries What is ZIO? Retries Repeats Schedule Composition
  • 18. What is ZIO? Retries Repeats Schedule Composition App Web API
  • 19. What is ZIO? Retries Repeats Schedule Composition App Web API 408
  • 20. What is ZIO? Retries Repeats Schedule Composition App Web API 408429
  • 21. What is ZIO? Retries Repeats Schedule Composition App Web API 408429 423
  • 22. What is ZIO? Retries Repeats Schedule Composition App Web API 408429 423 500
  • 23. What is ZIO? Retries Repeats Schedule Composition App Web API 408429 423 500 503
  • 24. What is ZIO? Retries Repeats Schedule Composition App Web API 408429 423 500 503 504
  • 25. What is ZIO? Retries Repeats Schedule Composition App Web API 408429 423 500 503 504
  • 26. What is ZIO? Retries Repeats Schedule Composition AppDatabase Cache Local Storage Cloud Storage Streaming Logs Analytics Web APIs
  • 27. def networkRequest(): A = ??? def networkRequestWithRetries(max: Int, millis: Long): A = { var i = 0 while (i < max) { try { return networkRequest() } catch { case _ : Exception => i = i + 1 Thread.sleep(millis) } } } What is ZIO? Retries Repeats Schedule Composition Retrying Synchronously
  • 28. Repeats What is ZIO? Retries Repeats Schedule Composition
  • 29. What is ZIO? Retries Repeats Schedule Composition App Generate Report
  • 30. What is ZIO? Retries Repeats Schedule Composition App Generate Report Every user
  • 31. What is ZIO? Retries Repeats Schedule Composition App Generate Report Every user Every day
  • 32. What is ZIO? Retries Repeats Schedule Composition App Generate Report Every user Every day Every account
  • 33. What is ZIO? Retries Repeats Schedule Composition App Generate Report Every user Every day Every account Every week
  • 34. What is ZIO? Retries Repeats Schedule Composition AppService Heartbeat Data Retrieval Remote Uploading Report Generation Log Rotation File Cleanup User Reminders Garbage Collection
  • 35. What is ZIO? Retries Repeats Schedule Composition def reportGen(): A = ??? def repeatedReportGen(max: Int, millis: Long): List[A] = { var list = List.empty[A] var i = 0 while (i < max) { list = reportGen() :: list Thread.sleep(millis) i = i + 1 } list } Repeating Synchronously
  • 36. Schedule What is ZIO? Retries Repeats Schedule Composition
  • 37. What is ZIO? Retries Repeats Schedule Composition ZIO SCHEDULE Schedule[A, B] Schedule[A, B] is an immutable value that describes an effectful schedule, which after consuming an A, produces a B and decides to halt or continue after some delay d.
  • 38. What is ZIO? Retries Repeats Schedule Composition ZIO SCHEDULE Schedule[A, B] A B B Continue? Continue after delay d Halt immediately
  • 39. What is ZIO? Retries Repeats Schedule Composition Should I repeat a program that failed with an E? Should I repeat a program that returned an A? Retries Repeats
  • 40. What is ZIO? Retries Repeats Schedule Composition Retries Repeats Schedule[E, B] Schedule[A, B] Retry policy Consumes errors of type E Emits values of type B Repeat policy Consumes return values of type A Emits values of type B
  • 41. What is ZIO? Retries Repeats Schedule Composition Schedule.never : Schedule[Any, Nothing] Zero Recurrences Accepts any input Never recurs, never emitting a value
  • 42. What is ZIO? Retries Repeats Schedule Composition Schedule.once : Schedule[Any, Unit] One Recurrence Accepts any input Recurs once, emitting unit
  • 43. What is ZIO? Retries Repeats Schedule Composition Schedule.forever : Schedule[Any, Int] Infinite Recurrences Consumes any input Recurs forever without delay, emitting the number of recurrences so far
  • 44. What is ZIO? Retries Repeats Schedule Composition Schedule.recurs(n: Int) : Schedule[Any, Int] Fixed Recurrences Accepts any input Recurs the specified number of times, emitting number of recurrences so far
  • 45. durationtask task What is ZIO? Retries Repeats Schedule Composition Schedule.spaced(d: Duration) : Schedule[Any, Int] Spaced Recurrences Accepts any input Recurs forever with delay, emitting the number of recurrences so far
  • 46. duration task task What is ZIO? Retries Repeats Schedule Composition Schedule.fixed(d: Duration) : Schedule[Any, Int] Fixed Recurrences Accepts any input Recurs forever with a delay, emitting number of recurrences so far duration
  • 47. What is ZIO? Retries Repeats Schedule Composition Schedule.exponential(d: Duration, f: Double = 2.0) : Schedule[Any, Duration] Exponential Recurrences Accepts any input Recurs forever with delay, emitting the current delay between steps Scaling factor Starting duration
  • 48. What is ZIO? Retries Repeats Schedule Composition Schedule.doWhile[A](f: A => Boolean): Schedule[A, A] Conditional Recurrences Accepts an A Recurs while the predicate is true without delay, emitting the same A Recurrence condition
  • 49. What is ZIO? Retries Repeats Schedule Composition Schedule.doUntil[A](f: A => Boolean): Schedule[A, A] Conditional Recurrences Accepts an A Recurs until the predicate is true without delay, emitting the same A Recurrence condition
  • 50. What is ZIO? Retries Repeats Schedule Composition Schedule.collect: Schedule[A, List[A]] Collecting Recurrences Recurs forever without delay, emitting a list of all consumed A’s Consumes an A
  • 51. What is ZIO? Retries Repeats Schedule Composition Schedule.identity[A]: Schedule[A, A] Identity Recurrences Recurs forever without delay, emitting the same A Consumes an A
  • 52. What is ZIO? Retries Repeats Schedule Composition Schedule.unfold[A](a: => A)(f: A => A): Schedule[Any, A] Unfold Recurrences Recurs forever without delay, emitting an A by unfolding the seed through repeated application Consumes any value
  • 53. What is ZIO? Retries Repeats Schedule Composition Schedule.point[A](a: => A): Schedule[Any, A] Constant Output Recurs forever without delay, emitting a constant Consumes any value
  • 54. What is ZIO? Retries Repeats Schedule Composition Schedule.lift[A, B](f: A => B): Schedule[A, B] Function Output Recurs forever without delay, emitting the function applied to the input Consumes an A
  • 55. What is ZIO? Retries Repeats Schedule Composition Retries Repeats val action: IO[E, A] = ??? val policy: Schedule[E, B] = ??? val retried: IO[E, A] = action retry policy val action: IO[E, A] = ??? val policy: Schedule[A, B] = ??? val repeated: IO[E, B] = action repeat policy
  • 56. What is ZIO? Retries Repeats Schedule Composition Retries Repeats val action: IO[E, A] = ??? val policy: Schedule[E, B] = ??? val orElse: (E, B) => IO[E2, A] = ??? val retried: IO[E2, A] = action retryOrElse (policy, orElse) val action: IO[E, A] = ??? val policy: Schedule[A, B] = ??? val orElse: (E, Option[B]) => IO[E2, B] = ??? val repeated: IO[E2, B] = action repeatOrElse (policy, onError)
  • 57. What is ZIO? Retries Repeats Schedule Composition Retries Repeats val action: IO[E, A] = ??? val policy: Schedule[E, B] = ??? val orElse: (E, B) => IO[E2, B] = ??? val retried: IO[E2, Either[B, A]] = action retryOrElse0 (policy, orElse) val action: IO[E, A] = ??? val policy: Schedule[A, B] = ??? val orElse: (E, Option[B]) => IO[E2, C] = ??? val repeated: IO[E2, Either[C, B]] = action repeatOrElse0 (policy, onError)
  • 58. Composition What is ZIO? Retries Repeats Schedule Composition
  • 59. What is ZIO? Retries Repeats Schedule Composition def networkRequestWithRetries(factor: Float = 1.5f, init: Int = 1, cur: Int = 0) (implicit as: ActorSystem): Future[String] = { networkRequest().recoverWith { case NetworkException => val next: Int = if (cur == 0) init else Math.ceil(cur * factor).toInt after(next.milliseconds, as.scheduler, global, Future.successful(1)).flatMap { _ => networkRequestWithRetries(factor, init, next) } case t: Throwable => throw t } } Future Retries* * https://hackernoon.com/exponential-back-off-with-scala-futures-7426340d0069
  • 60. What is ZIO? Retries Repeats Schedule Composition def retry[F[_]: Timer: RaiseThrowable, O]( fo : F[O], delay : FiniteDuration, nextDelay : FiniteDuration => FiniteDuration, maxAttempts : Int, retriable : Throwable => Boolean): Stream[F, O] = ??? FS2 Retry
  • 61. What is ZIO? Retries Repeats Schedule Composition Monix Retry & Repeat Retries Repeats val task : Task[A] = ??? val retries: Int = ??? val retried1: Task[A] = task onErrorRestart (retries) val pred: Throwable => Boolean = ??? val retried2: Task[A] = task onErrorRestartIf (pred) // onErrorRestartLoop val task: Task[A] = ??? val pred: A => Boolean = ??? val repeated: Task[A] = task restartUntil (pred)
  • 62. What is ZIO? Retries Repeats Schedule Composition ZIO SCHEDULE Monoid append zero
  • 63. What is ZIO? Retries Repeats Schedule Composition ZIO SCHEDULE Monoid append zero Applicative map point ap
  • 64. What is ZIO? Retries Repeats Schedule Composition ZIO SCHEDULE Monoid append zero Applicative map point ap Category id compose
  • 65. What is ZIO? Retries Repeats Schedule Composition ZIO SCHEDULE Monoid append zero Applicative map point ap Category id compose Profunctor lmap rmap dimap
  • 66. What is ZIO? Retries Repeats Schedule Composition ZIO SCHEDULE Monoid append zero Applicative map point ap Category id compose Profunctor lmap rmap dimap Strong first second
  • 67. What is ZIO? Retries Repeats Schedule Composition ZIO SCHEDULE Monoid append zero Applicative map point ap Category id compose Profunctor lmap rmap dimap Strong first second Choice left right
  • 68. What is ZIO? Retries Repeats Schedule Composition (s1 : Schedule[A, B]) && (s2 : Schedule[A, C]) : Schedule[A, (B, C)] Intersection s1 s2 s1 && s2 Continue : Boolean b1 b2 b1 && b2 Delay : Duration d1 d2 d1.max(d2) Emit : (A, B) a b (a, b)
  • 69. What is ZIO? Retries Repeats Schedule Composition (s1 : Schedule[A, B]) || (s2 : Schedule[A, C]) : Schedule[A, (B, C)] Union s1 s2 s1 || s2 Continue : Boolean b1 b2 b1 || b2 Delay : Duration d1 d2 d1.min(d2) Emit : (A, B) a b (a, b)
  • 70. What is ZIO? Retries Repeats Schedule Composition (s1 : Schedule[A, B]) andThen (s2 : Schedule[A, C]) : Schedule[A, Either[B, C]] Sequence A A B C s1 s2 s1 andThen s2A Either[B, C]
  • 71. What is ZIO? Retries Repeats Schedule Composition (s1 : Schedule[A, B]) >>> (s2 : Schedule[B, C]) : Schedule[A, C] Compose A B B C s1 s2 s1 >>> s2A C
  • 72. What is ZIO? Retries Repeats Schedule Composition (s1 : Schedule[A, B]).jittered : Schedule[A, B] Jittering A AB Bs1 s1’ Delays randomly jittered
  • 73. What is ZIO? Retries Repeats Schedule Composition (s1 : Schedule[A, B]).collect : Schedule[A, List[B]] Collecting A AB List[C]s1 s1’ Emissions collected
  • 74. What is ZIO? Retries Repeats Schedule Composition (s1 : Schedule[A, B]).whileInput(f: A => Boolean) : Schedule[A, B] Filtering By Input A AB Bs1 s1’ Continues while/until f returns true (s1 : Schedule[A, B]).untilInput(f: A => Boolean) : Schedule[A, B]
  • 75. What is ZIO? Retries Repeats Schedule Composition (s1 : Schedule[A, B]).whileOutput(f: B => Boolean) : Schedule[A, B] Filtering By Output A AB Bs1 s1’ Continues while/until f returns true (s1 : Schedule[A, B]).untilOutput(f: B => Boolean) : Schedule[A, B]
  • 76. What is ZIO? Retries Repeats Schedule Composition (s1 : Schedule[A, B]).map(f: B => C) : Schedule[A, C] Mapping A AB Cs1 s1’ B mapped to C
  • 77. What is ZIO? Retries Repeats Schedule Composition (s1 : Schedule[A, B]) *> (s2 : Schedule[A, C]) : Schedule[A, C] (s1 && s2).map(_._2) Left / Right Ap (s1 : Schedule[A, B]) <* (s2 : Schedule[A, C]) : Schedule[A, B] (s1 && s2).map(_._1)
  • 78. What is ZIO? Retries Repeats Schedule Composition (s1 : Schedule[A, B]).logInput(f: A => IO[Nothing, Unit]) : Schedule[A, B] Logging Inputs A AB Bs1 s1’ Inputs logged to f
  • 79. What is ZIO? Retries Repeats Schedule Composition (s1 : Schedule[A, B]).logOutput(f: B => IO[Nothing, Unit]) : Schedule[A, B] Logging Outputs A AB Bs1 s1’ Outputs logged to f
  • 80. What is ZIO? Retries Repeats Schedule Composition Crafting a ZIO Schedule Produce a jittered schedule that first does exponential spacing (starting from 10 milliseconds), but then after the spacing reaches 60 seconds, switches over to fixed spacing of 60 seconds between recurrences, but will only do that for up to 100 times, and emits a list of the collected inputs.
  • 81. What is ZIO? Retries Repeats Schedule Composition Crafting a ZIO Schedule Produce a jittered schedule that first does exponential spacing (starting from 10 milliseconds), but then after the spacing reaches 60 seconds, switches over to fixed spacing of 60 seconds between recurrences, but will only do that for up to 100 times, and emits a list of the collected inputs.
  • 82. What is ZIO? Retries Repeats Schedule Composition Crafting a ZIO Schedule Produce a jittered schedule that first does exponential spacing (starting from 10 milliseconds), but then after the spacing reaches 60 seconds, switches over to fixed spacing of 60 seconds between recurrences, but will only do that for up to 100 times, and emits a list of the collected inputs. Schedule.exponential(10.milliseconds)
  • 83. What is ZIO? Retries Repeats Schedule Composition Crafting a ZIO Schedule Produce a jittered schedule that first does exponential spacing (starting from 10 milliseconds), but then after the spacing reaches 60 seconds, switches over to fixed spacing of 60 seconds between recurrences, but will only do that for up to 100 times, and emits a list of the collected inputs. (Schedule.exponential(10.milliseconds) andThen ???)
  • 84. What is ZIO? Retries Repeats Schedule Composition Crafting a ZIO Schedule Produce a jittered schedule that first does exponential spacing (starting from 10 milliseconds), but then after the spacing reaches 60 seconds, switches over to fixed spacing of 60 seconds between recurrences, but will only do that for up to 100 times, and emits a list of the collected inputs. (Schedule.exponential(10.milliseconds).whileOutput(_ < 60.seconds) andThen ???)
  • 85. What is ZIO? Retries Repeats Schedule Composition Crafting a ZIO Schedule Produce a jittered schedule that first does exponential spacing (starting from 10 milliseconds), but then after the spacing reaches 60 seconds, switches over to fixed spacing of 60 seconds between recurrences, but will only do that for up to 100 times, and emits a list of the collected inputs. (Schedule.exponential(10.milliseconds).whileOutput(_ < 60.seconds) andThen Schedule.fixed(60.seconds))
  • 86. What is ZIO? Retries Repeats Schedule Composition Crafting a ZIO Schedule Produce a jittered schedule that first does exponential spacing (starting from 10 milliseconds), but then after the spacing reaches 60 seconds, switches over to fixed spacing of 60 seconds between recurrences, but will only do that for up to 100 times, and emits a list of the collected inputs. (Schedule.exponential(10.milliseconds).whileOutput(_ < 60.seconds) andThen (Schedule.fixed(60.seconds) && Schedule.recurs(100))
  • 87. What is ZIO? Retries Repeats Schedule Composition Crafting a ZIO Schedule Produce a jittered schedule that first does exponential spacing (starting from 10 milliseconds), but then after the spacing reaches 60 seconds, switches over to fixed spacing of 60 seconds between recurrences, but will only do that for up to 100 times, and emits a list of the collected inputs. (Schedule.exponential(10.milliseconds).whileOutput(_ < 60.seconds) andThen (Schedule.fixed(60.seconds) && Schedule.recurs(100)).jittered
  • 88. What is ZIO? Retries Repeats Schedule Composition Crafting a ZIO Schedule Produce a jittered schedule that first does exponential spacing (starting from 10 milliseconds), but then after the spacing reaches 60 seconds, switches over to fixed spacing of 60 seconds between recurrences, but will only do that for up to 100 times, and emits a list of the collected inputs. (Schedule.exponential(10.milliseconds).whileOutput(_ < 60.seconds) andThen (Schedule.fixed(60.seconds) && Schedule.recurs(100)).jittered *> Schedule.identity[A].collect
  • 89. What is ZIO? Retries Repeats Schedule Composition Crafting a ZIO Schedule Produce a jittered schedule that first does exponential spacing (starting from 10 milliseconds), but then after the spacing reaches 60 seconds, switches over to fixed spacing of 60 seconds between recurrences, but will only do that for up to 100 times, and emits a list of the collected inputs. def customSchedule[A]: Schedule[A, List[A]] = { import Schedule._ (exponential(10.millis).whileOutput(_ < 60.secs) andThen (fixed(60.secs) && recurs(100)).jittered *> identity[A].collect }
  • 91. Functional Scala by John A. De Goes Local Remote Date London London Time Oct 21 - 23 Paris Paris Time Oct 25 - 27 SF / SV Pacific Coast Time Nov 18 - 21 That’s A Wrap!
  • 92. THANK YOU! @jdegoes - http://degoes.net That’s A Wrap!