Pudu programming language
Menu
Package

@chrismichaelps / pudu-lang-resilience

Resilience pipelines for Pudu: retry, circuit breaker, timeout, fallback, hedging, rate limiting, and chaos injection

0.1.0Apache-2.01

InstallClose

PuduLangResilience.pudu

Pudu82 lines2.6 KB

GitHub ↗
1/** @Resilience.Root.Vocabulary — outcomes and failures of guarded executions */2module PuduLangResilience34import PuduLangResilience.Constants.Messages as Messages5import PuduLangResilience.Utils.Template as Template67/** @Resilience.Root.Failure — why a guarded execution produced no value */8export type Failure[E]9  = Raised(E)10  | TimedOut(Int)11  | BrokenCircuit(Int)12  | IsolatedCircuit13  | RateLimited(Option[Int])14  | Cancelled(Str)15  | Crashed(Str)1617/** @Resilience.Root.Outcome — the value or failure of one execution */18export type Outcome[T, E] = Result[T, Failure[E]]1920/// An outcome holding a value.21export fn succeed[T, E](value: T) -> Outcome[T, E] { Ok(value) }2223/// An outcome holding the callback's own error.24export fn raise[T, E](problem: E) -> Outcome[T, E] { Err(Raised(problem)) }2526/// The outcome of a callback that answers a plain `Result`.27export fn lift[T, E](result: Result[T, E]) -> Outcome[T, E] {28  match result {29    case Ok(value) => Ok(value)30    case Err(problem) => Err(Raised(problem))31  }32}3334/// The callback's own error, when the failure is one.35export fn raised[E](failure: &Failure[E]) -> Option[E] {36  match failure {37    case Raised(problem) => Some(problem)38    case _ => None39  }40}4142/// Whether the failure is a cancellation.43export fn isCancellation[E](failure: &Failure[E]) -> Bool {44  match failure {45    case Cancelled(_) => true46    case _ => false47  }48}4950/// Whether the failure is a rejection by a strategy rather than the callback's own error.51export fn isRejection[E](failure: &Failure[E]) -> Bool {52  match failure {53    case TimedOut(_) => true54    case BrokenCircuit(_) => true55    case IsolatedCircuit => true56    case RateLimited(_) => true57    case _ => false58  }59}6061/// One sentence saying what went wrong.62export fn describe[E](failure: &Failure[E]) -> Str {63  match failure {64    case Raised(problem) => Template.fill(Messages.RAISED, &[show(problem)])65    case TimedOut(millis) => Template.fill(Messages.TIMED_OUT, &[show(millis)])66    case BrokenCircuit(millis) => Template.fill(Messages.BROKEN_CIRCUIT, &[show(millis)])67    case IsolatedCircuit => Messages.ISOLATED_CIRCUIT68    case RateLimited(Some(millis)) => Template.fill(Messages.RATE_LIMITED_AFTER, &[show(millis)])69    case RateLimited(None) => Messages.RATE_LIMITED70    case Cancelled(reason) => Template.fill(Messages.CANCELLED, &[reason])71    case Crashed(reason) => Template.fill(Messages.CRASHED, &[reason])72  }73}7475/// One line naming an outcome, for telemetry.76export fn summarize[T, E](outcome: &Outcome[T, E]) -> Str {77  match outcome {78    case Ok(value) => Template.fill(Messages.SUCCEEDED, &[show(value)])79    case Err(failure) => describe(&failure)80  }81}82