
Behavior.pudu
Pudu57 lines2.3 KB
1/** @Chaos.Behavior.Strategy — runs extra behavior before the callback */2module PuduLangResilience.Chaos.Behavior34import PuduLangResilience.Chaos as Chaos5import PuduLangResilience.Constants.Events as Events6import PuduLangResilience.Context as Context7import PuduLangResilience as Resilience8import PuduLangResilience.Strategy as Strategy9import PuduLangResilience.Telemetry as Telemetry1011/** @Chaos.Behavior.Options — what to run and how often */12export type Options[E] = {13 name: Option[Str],14 injection: Chaos.Injection,15 behavior: Option[fn(Chaos.Arguments) -> Result[(), Resilience.Failure[E]]],16 onInjected: Option[fn(Context.Context) -> ()]17}181920export fn defaults[E]() -> Options[E] { Options{name: None, injection: Chaos.defaults(), behavior: None, onInjected: None} }212223export fn injecting[E](behavior: fn(Chaos.Arguments) -> Result[(), Resilience.Failure[E]], injection: Chaos.Injection) -> Options[E] {24 Options{..defaults(), injection: injection, behavior: Some(behavior)}25}262728export fn validate[E](options: &Options[E]) -> Array[Str] {29 var problems = Chaos.validate(&options.injection)30 if options.behavior == None { problems = problems.push("behavior is required") }31 problems32}33343536export fn strategy[T, E](options: Options[E]) -> Strategy.Strategy[T, E] {37 Strategy.Strategy {38 name: options.name,39 kind: "ChaosBehavior",40 summary: "injects behavior at rate " + show(options.injection.rate),41 problems: validate(&options),42 attach: Strategy.detached,43 execute: fn(runtime: Strategy.Runtime, context: Context.Context, callback: Strategy.Callback[T, E]) -> Resilience.Outcome[T, E] {44 if !Chaos.shouldInject(&options.injection, &context, &runtime.randomizer) { return callback(context) }45 match options.behavior {46 case Some(behave) => {47 Telemetry.report(&runtime.telemetry, &context, Events.ON_BEHAVIOR, Telemetry.Information, None, Telemetry.BehaviorInjected)48 behave(Chaos.arguments(&context, &runtime.randomizer)) ?49 if let Some(notify) = options.onInjected { notify(context) }50 callback(context)51 }52 case None => callback(context)53 }54 }55 }56}57