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

ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022Alexander Ioffe
 
Capabilities for Resources and Effects
Capabilities for Resources and EffectsCapabilities for Resources and Effects
Capabilities for Resources and EffectsMartin Odersky
 
Algebraic Thinking for Evolution of Pure Functional Domain Models
Algebraic Thinking for Evolution of Pure Functional Domain ModelsAlgebraic Thinking for Evolution of Pure Functional Domain Models
Algebraic Thinking for Evolution of Pure Functional Domain ModelsDebasish Ghosh
 
Implementing the IO Monad in Scala
Implementing the IO Monad in ScalaImplementing the IO Monad in Scala
Implementing the IO Monad in ScalaHermann Hueck
 
Sequence and Traverse - Part 1
Sequence and Traverse - Part 1Sequence and Traverse - Part 1
Sequence and Traverse - Part 1Philip Schwarz
 
Error Management: Future vs ZIO
Error Management: Future vs ZIOError Management: Future vs ZIO
Error Management: Future vs ZIOJohn De Goes
 
Design Principles for a High-Performance Smalltalk
Design Principles for a High-Performance SmalltalkDesign Principles for a High-Performance Smalltalk
Design Principles for a High-Performance SmalltalkESUG
 
Domain Modeling in a Functional World
Domain Modeling in a Functional WorldDomain Modeling in a Functional World
Domain Modeling in a Functional WorldDebasish Ghosh
 
Python programming workshop session 1
Python programming workshop session 1Python programming workshop session 1
Python programming workshop session 1Abdul Haseeb
 
Why functional programming and category theory strongly matters
Why functional programming and category theory strongly mattersWhy functional programming and category theory strongly matters
Why functional programming and category theory strongly mattersPiotr Paradziński
 
The Functional Programming Triad of Map, Filter and Fold
The Functional Programming Triad of Map, Filter and FoldThe Functional Programming Triad of Map, Filter and Fold
The Functional Programming Triad of Map, Filter and FoldPhilip Schwarz
 
2 years with python and serverless
2 years with python and serverless2 years with python and serverless
2 years with python and serverlessHector Canto
 
Functional Error Handling with Cats
Functional Error Handling with CatsFunctional Error Handling with Cats
Functional Error Handling with CatsMark Canlas
 
ZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in ScalaZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in ScalaWiem Zine Elabidine
 

What's hot (20)

ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022
 
Capabilities for Resources and Effects
Capabilities for Resources and EffectsCapabilities for Resources and Effects
Capabilities for Resources and Effects
 
Algebraic Thinking for Evolution of Pure Functional Domain Models
Algebraic Thinking for Evolution of Pure Functional Domain ModelsAlgebraic Thinking for Evolution of Pure Functional Domain Models
Algebraic Thinking for Evolution of Pure Functional Domain Models
 
Implementing the IO Monad in Scala
Implementing the IO Monad in ScalaImplementing the IO Monad in Scala
Implementing the IO Monad in Scala
 
Sequence and Traverse - Part 1
Sequence and Traverse - Part 1Sequence and Traverse - Part 1
Sequence and Traverse - Part 1
 
Preparing for Scala 3
Preparing for Scala 3Preparing for Scala 3
Preparing for Scala 3
 
Error Management: Future vs ZIO
Error Management: Future vs ZIOError Management: Future vs ZIO
Error Management: Future vs ZIO
 
Design Principles for a High-Performance Smalltalk
Design Principles for a High-Performance SmalltalkDesign Principles for a High-Performance Smalltalk
Design Principles for a High-Performance Smalltalk
 
scalar.pdf
scalar.pdfscalar.pdf
scalar.pdf
 
ZIO Queue
ZIO QueueZIO Queue
ZIO Queue
 
Domain Modeling in a Functional World
Domain Modeling in a Functional WorldDomain Modeling in a Functional World
Domain Modeling in a Functional World
 
Python programming workshop session 1
Python programming workshop session 1Python programming workshop session 1
Python programming workshop session 1
 
Why functional programming and category theory strongly matters
Why functional programming and category theory strongly mattersWhy functional programming and category theory strongly matters
Why functional programming and category theory strongly matters
 
Beyond Scala Lens
Beyond Scala LensBeyond Scala Lens
Beyond Scala Lens
 
The Functional Programming Triad of Map, Filter and Fold
The Functional Programming Triad of Map, Filter and FoldThe Functional Programming Triad of Map, Filter and Fold
The Functional Programming Triad of Map, Filter and Fold
 
Zio in real world
Zio in real worldZio in real world
Zio in real world
 
2 years with python and serverless
2 years with python and serverless2 years with python and serverless
2 years with python and serverless
 
Functional Error Handling with Cats
Functional Error Handling with CatsFunctional Error Handling with Cats
Functional Error Handling with Cats
 
ZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in ScalaZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in Scala
 
MySQL Cheat Sheet
MySQL Cheat SheetMySQL Cheat Sheet
MySQL Cheat Sheet
 

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
 
MCE^3 - Jorge D. Ortiz - Fuentes - Escape From Mars
MCE^3 - Jorge D. Ortiz - Fuentes - Escape From Mars MCE^3 - Jorge D. Ortiz - Fuentes - Escape From Mars
MCE^3 - Jorge D. Ortiz - Fuentes - Escape From Mars PROIDEA
 

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

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
 
MCE^3 - Jorge D. Ortiz - Fuentes - Escape From Mars
MCE^3 - Jorge D. Ortiz - Fuentes - Escape From Mars MCE^3 - Jorge D. Ortiz - Fuentes - Escape From Mars
MCE^3 - Jorge D. Ortiz - Fuentes - Escape From Mars
 

More from John De Goes

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

One Monad to Rule Them All
One Monad to Rule Them AllOne Monad to Rule Them All
One Monad to Rule Them All
 
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

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
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
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
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
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
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
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
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesZilliz
 
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
 
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
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embeddingZilliz
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 

Recently uploaded (20)

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
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
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
 
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
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
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
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
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
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector Databases
 
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
 
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
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embedding
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 

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!