Skip to content

Commit

Permalink
cleanup scenario for hedging #bill #james #time 30m
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesward committed Jul 26, 2024
1 parent 89878e4 commit 89600f3
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 58 deletions.
77 changes: 20 additions & 57 deletions Chapters/09_Resilience.md
Original file line number Diff line number Diff line change
Expand Up @@ -657,85 +657,51 @@ import zio.*
import zio.direct.*
import zio.Console.*

object Scenario:
def apply(
z: ZIO[Any, String, Unit]
): ZLayer[Any, Nothing, Unit] =
Runtime.setConfigProvider:
StaticConfigProvider(z)

// This configuration is used by Effects to get the scenario that
// may have been passed in via `bootstrap`
// The configuration is optional and the default of `Config.fail`
// sets the Option to None.
val scenarioConfig: Config[
Option[ZIO[Any, String, Unit]]
] =
Config.Optional[ZIO[Any, String, Unit]]:
Config.fail("no default scenario")

class StaticConfigProvider(
z: ZIO[Any, String, Unit]
) extends ConfigProvider:
override def load[A](config: Config[A])(
implicit trace: Trace
): IO[Config.Error, A] =
ZIO.succeed:
Some(z).asInstanceOf[A]

val sometimesSlowRequest =
defer:
if Random.nextIntBounded(1_000).run == 0
then
ZIO.sleep(3.second).run

// based on our config from bootstrap, make the request with the additional logic
val makeRequest =
defer:
ZIO.config(scenarioConfig).run match
case Some(z: ZIO[Any, String, Unit]) =>
z.run
case _ =>
ZIO.fail("No scenario")
case class Scenario(
effect: ZIO[Any, Nothing, Unit]
)
```

```scala 3 mdoc:silent
// TODO not sure yet how I feel about this
// It should be a def that takes a ZIO, but we are avoiding that
val makeLotsOfRequests =
import zio.*
import zio.direct.*

def makeLotsOfRequests(scenario: Scenario) =
defer:
val totalRequests = 50_000

val failOnBreach =
scenario
.effect
.timeoutFail("took too long"):
1.second

val successes =
ZIO
.collectAllSuccessesPar:
List
.fill(totalRequests)(makeRequest)
List.fill(totalRequests):
failOnBreach
.run

val contractBreaches =
totalRequests - successes.length

"Contract Breaches: " + contractBreaches
```

```scala 3 mdoc:silent
val requestWithTimeout =
sometimesSlowRequest
.timeoutFail("took too long"):
1.second
"Contract Breaches: $contractBreaches"
```

```scala 3 mdoc:runzio:liveclock
import zio.*
import zio.direct.*

override val bootstrap =
Scenario:
requestWithTimeout

def run =
makeLotsOfRequests
makeLotsOfRequests:
Scenario(sometimesSlowRequest)
```

Sadly, we have breached our contract many times in this scenario.
Expand All @@ -752,12 +718,9 @@ val hedged =
import zio.*
import zio.direct.*

override val bootstrap =
Scenario:
hedged

def run =
makeLotsOfRequests
makeLotsOfRequests:
Scenario(hedged)
```

## Test Resilience
Expand Down

0 comments on commit 89600f3

Please sign in to comment.