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

Shared.pudu

Pudu39 lines1.3 KB

GitHub ↗
1/** @Utils.Shared.Module — mutable state shared between threads */2module PuduLangResilience.Utils.Shared34import Std.Sync as Sync56/** @Utils.Shared.Shared — a value changed only under its lock */7export type Shared[S] = { lock: Sync.Mutex, held: Sync.Cell[S] }89/// A shared value starting at `initial`.10export fn shared[S](initial: S) -> Shared[S] { Shared{lock: Sync.mutex(), held: Sync.cell(initial)} }1112/// The value as it stands.13export fn current[S](source: &Shared[S]) -> S {14  match Sync.get(&source.held) {15    case Ok(value) => value16    case Err(problem) => panic("shared state could not be read: " + show(problem))17  }18}1920/// Replaces the value with the first half of what `step` answers for it, and answers the second21/// half. No other change to the same value runs between the read and the write.22export fn change[S, R](target: &Shared[S], step: fn(S) -> (S, R)) -> R {23  let held = target.held24  let outcome = Sync.withLock(&target.lock, fn() -> R {25      let next = step(current(target))26      let _stored = Sync.set(&held, next[0])27      next[1]28    })29  match outcome {30    case Ok(answer) => answer31    case Err(problem) => panic("shared state could not be locked: " + show(problem))32  }33}3435/// Replaces the value with what `step` answers for it.36export fn update[S](target: &Shared[S], step: fn(S) -> S) -> () {37  change(target, fn(value: S) -> (S, ()) { (step(value), ()) })38}39