///|
pub(all) struct RetryAdvice {
should_retry : Bool
wait_ms : Int
message : String
} derive(Eq, Debug)
///|
pub fn RetryAdvice::from_decision(decision : Decision) -> RetryAdvice {
if decision.is_allowed() {
RetryAdvice::{
should_retry: false,
wait_ms: 0,
message: "request accepted",
}
} else {
RetryAdvice::{
should_retry: true,
wait_ms: decision.retry_after_ms(),
message: "retry after \{decision.retry_after_ms()}ms",
}
}
}
///|
pub fn RetryAdvice::should_retry(self : RetryAdvice) -> Bool {
self.should_retry
}
///|
pub fn RetryAdvice::wait_ms(self : RetryAdvice) -> Int {
self.wait_ms
}
///|
pub fn RetryAdvice::message(self : RetryAdvice) -> String {
self.message
}
///|
pub(all) struct RetrySchedule {
base_ms : Int
max_ms : Int
factor : Int
} derive(Eq, Debug)
///|
pub fn RetrySchedule::exponential(
base_ms : Int,
max_ms : Int,
factor? : Int = 2,
) -> RetrySchedule {
RetrySchedule::{
base_ms: positive(base_ms, 1),
max_ms: positive(max_ms, 1),
factor: positive(factor, 1),
}
}
///|
pub fn RetrySchedule::delay_at(self : RetrySchedule, attempt : Int) -> Int {
let mut delay = self.base_ms
for _ in 0..= self.max_ms {
return self.max_ms
}
}
if delay > self.max_ms {
self.max_ms
} else {
delay
}
}
///|
pub fn RetrySchedule::delays(
self : RetrySchedule,
attempts : Int,
) -> Array[Int] {
let values : Array[Int] = []
for i in 0.. String {
let values = self.delays(attempts)
let mut out = "retry"
for value in values {
out = out + " " + value.to_string() + "ms"
}
out
}
///|
pub fn Decision::explain(self : Decision) -> String {
match self {
Allowed(info) =>
"allowed remaining=\{info.remaining} reset_after_ms=\{info.reset_after_ms}"
Rejected(info) =>
"rejected retry_after_ms=\{info.retry_after_ms} reason=\{info.reason}"
}
}
///|
pub fn LimitSpec::explain(self : LimitSpec) -> String {
match self.kind {
TokenBucket =>
"token_bucket \{self.spec_name}: capacity=\{self.first} refill=\{self.second}/\{self.third}ms"
FixedWindow =>
"fixed_window \{self.spec_name}: limit=\{self.first} window=\{self.second}ms"
SlidingLog =>
"sliding_log \{self.spec_name}: limit=\{self.first} window=\{self.second}ms"
GcraSpec =>
"gcra \{self.spec_name}: limit=\{self.first} period=\{self.second}ms burst=\{self.third}"
}
}