1/** @Resilience.Chaos.Module — when a chaos strategy injects */2modulePuduLangResilience.Chaos34importStd.DecimalasDecimal5importPuduLangResilience.ContextasContext6importPuduLangResilience.RandomizerasRandomizer78/** @Resilience.Chaos.Injection — how often, and whether, chaos is injected */9exporttypeInjection = {10 rate: Decimal,11 rateGenerator: Option[fn(Context.Context) -> Decimal],12 enabled: Bool,13 enabledGenerator: Option[fn(Context.Context) -> Bool]14}1516/** @Resilience.Chaos.Arguments — what a chaos generator decides from */17exporttypeArguments = { context: Context.Context, randomizer: Randomizer.Randomizer }1819/// Enabled, injecting into one execution in a thousand.20exportfndefaults() -> Injection { Injection{rate: 0.001d, rateGenerator: None, enabled: true, enabledGenerator: None} }2122/// Enabled, injecting into every execution.23exportfnalways() -> Injection { Injection{..defaults(), rate: 1d} }2425/// Enabled, injecting into the given share of executions, from 0 to 1.26exportfnatRate(rate: Decimal) -> Injection { Injection{..defaults(), rate: rate} }2728/// Every reason the injection settings cannot be followed.29exportfnvalidate(injection: &Injection) -> Array[Str] {30if injection.rate < 0d || injection.rate > 1d { ["rate must be from 0 to 1"] } else { [] }31}3233/// Whether to inject into the execution holding `context`: never while disabled, otherwise with34/// the probability the rate names. A generated rate outside 0 to 1 is taken as the nearer bound.35exportfnshouldInject(injection: &Injection, context: &Context.Context, randomizer: &Randomizer.Randomizer) -> Bool {36let enabled = match injection.enabledGenerator {37caseSome(decide) => decide(*context)38caseNone => injection.enabled39 }40if !enabled { returnfalse }41let rate = match injection.rateGenerator {42caseSome(generate) => generate(*context)43caseNone => injection.rate44 }45Randomizer.chance(randomizer, rate)46}4748/// The arguments chaos generators receive for one execution.49exportfnarguments(context: &Context.Context, randomizer: &Randomizer.Randomizer) -> Arguments {50Arguments{context: *context, randomizer: *randomizer}51}52