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.