yoshuawuyts / exponential-backoff

Exponential backoff generator with jitter.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Iter is !Send + !Sync. Use StdRng to make it threadsafe.

hgzimmerman opened this issue Β· comments

Choose one: a πŸ™‹ feature request

Using this library in async contexts is difficult due to the fact that the Iter is not Send and Sync.
This is because the Iter holds onto a ThreadRng which is !Send + !Sync.

Instead of using a ThreadRng, you could instead use a StdRng, which is threadsafe.
ThreadRng uses StdRng under the hood (behind a wrapper for reseeding it).
Because I don't think your exponential backoff timers need the additional protection, I've opted to not propose to use the reseeding wrapper, let me know if you think otherwise.

I'm happy to implement this change should you indicate you would merge it.

Context

I would like to use this library in an async context where I use it to retry database calls. I would like to call tokio::time::delay_for(...).await instead of std::thread::sleep(...), but because the iter isn't thread safe, I can't.

Code Sample

/// Immutable iterator.
#[derive(Debug, Clone)]
pub struct Iter<'b> {
    inner: &'b Backoff,
    rng: StdRng,
    retry_count: u32,
}
impl<'b> Iter<'b> {
    #[inline]
    pub fn new(inner: &'b Backoff) -> Self {
        Self {
            inner,
            retry_count: 0,
            rng: StdRng::from_entropy(),
        }
    }
}

I just ran into this. I'm unable to use this crate as is, unfortunately.