
Resilient.pudu
Pudu47 lines2.2 KB
1/** @Mediator.Behaviors.Resilient.Module — requests run through a resilience pipeline */2module PuduLangMediator.Behaviors.Resilient34import PuduLangMediator.Context as Context5import PuduLangMediator as Messaging6import PuduLangMediator.Registration as Registration7import PuduLangMediator.Request as Request8import PuduLangResilience.Context as Guard9import PuduLangResilience.Pipeline as Pipeline10import PuduLangResilience as Resilience111213141516export fn behavior[Q, R, E](pipeline: Pipeline.Pipeline[R, Messaging.Failure[E]]) -> Request.Behavior[Q, R, E] {17 fn(_request: Q, context: Context.Context, next: Request.Next[R, E]) -> Messaging.Outcome[R, E] {18 let outcome = Pipeline.executeWith(&pipeline, Guard.cancellable(context.token), fn(attempt: Guard.Context) -> Resilience.Outcome[R, Messaging.Failure[E]] {19 match next(Context.withToken(&context, attempt.token)) {20 case Ok(value) => Ok(value)21 case Err(Messaging.Cancelled(reason)) => Err(Resilience.Cancelled(reason))22 case Err(failure) => Err(Resilience.Raised(failure))23 }24 })25 match outcome {26 case Ok(value) => Ok(value)27 case Err(failure) => Err(translated(&failure))28 }29 }30}313233export fn register[Q, R, E](subject: &Request.Kind[Q, R, E], pipeline: Pipeline.Pipeline[R, Messaging.Failure[E]]) -> Registration.Registration {34 Registration.behavior(subject, behavior(pipeline))35}36373839export fn translated[E](failure: &Resilience.Failure[Messaging.Failure[E]]) -> Messaging.Failure[E] {40 match failure {41 case Resilience.Raised(inner) => inner42 case Resilience.Cancelled(reason) => Messaging.Cancelled(reason)43 case Resilience.Crashed(reason) => Messaging.Crashed(reason)44 case rejection => Messaging.Refused(Resilience.describe(&rejection))45 }46}47