Next iteration with backoffs, tasks, basic skeleton for events
This commit is contained in:
80
src/backoff.rs
Normal file
80
src/backoff.rs
Normal file
@@ -0,0 +1,80 @@
|
||||
use embassy_time::{Duration, Timer};
|
||||
use log::warn;
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct Backoff {
|
||||
delay: Duration,
|
||||
attempts: Attempts,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum Attempts {
|
||||
Finite(u64),
|
||||
Forever
|
||||
}
|
||||
|
||||
impl Iterator for Attempts {
|
||||
type Item = Self;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
match *self {
|
||||
Attempts::Forever => Some(Attempts::Forever),
|
||||
Attempts::Finite(0) => None,
|
||||
Attempts::Finite(n) => {
|
||||
*self = Attempts::Finite(n - 1);
|
||||
Some(Attempts::Finite(n))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Backoff {
|
||||
pub fn from_millis(millis: u64) -> Self {
|
||||
Self {
|
||||
delay: Duration::from_millis(millis),
|
||||
attempts: Attempts::Finite(3),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_secs(secs: u64) -> Self {
|
||||
Self {
|
||||
delay: Duration::from_secs(secs),
|
||||
attempts: Attempts::Finite(3),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn forever(self) -> Self {
|
||||
Self {
|
||||
attempts: Attempts::Forever,
|
||||
..self
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn attempt<F: AsyncFnMut() -> Result<T, E>, T, E: core::fmt::Debug>(self, mut f: F) -> Result<T, E> {
|
||||
let mut latest= f().await;
|
||||
let mut delay = self.delay;
|
||||
'outer: loop {
|
||||
for attempt in self.attempts {
|
||||
match &latest {
|
||||
Err(e) => {
|
||||
match attempt {
|
||||
Attempts::Finite(1) => {
|
||||
warn!("Operation failed on final attempt.");
|
||||
break 'outer
|
||||
}
|
||||
attempt => {
|
||||
warn!("Operation failed. Retrying attempt {attempt:?} after {delay}");
|
||||
Timer::after(delay).await;
|
||||
delay *= 2;
|
||||
latest = f().await
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => break 'outer
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
latest
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user