Hi lovely helpful people!
I have made a simple crate for generating random "lorem ipsum" text: lipsum. It uses a Markov chain internally to generate the text. Currently, the code use the thread-local random number generator directly when it needs some randomness. It looks similar to this:
let mut rng = rand::thread_rng();
let next = rng.choose(next_words).unwrap();
I would like to store the RNG in the MarkovChain
struct instead. That way you can seed the RNG and get consistent output when needed.
However, I am also initializing a static MarkovChain
value with lazy_static!
β this is to save the overhead of training the chain every time a bit of lorem ipsum text is needed.
Expanding the MarkovChain
struct to
pub struct MarkovChain<'a> {
pub map: HashMap<Bigram<'a>, Vec<&'a str>>,
pub rng: rand::ThreadRng, // <-- the new struct field
}
gives me this lovely error message when compiling the code:
error[E0277]: the trait bound `std::rc::Rc<std::cell::RefCell<rand::reseeding::ReseedingRng<rand::StdRng, rand::ThreadRngReseeder>>>: std::marker::Sync` is not satisfied in `MarkovChain<'static>`
--> src/lib.rs:213:1
|
213 | / lazy_static! {
214 | | /// Markov chain generating lorem ipsum text.
215 | | static ref LOREM_IPSUM_CHAIN: MarkovChain<'static> = {
216 | | let mut chain = MarkovChain::new();
... |
220 | | };
221 | | }
| |_^ `std::rc::Rc<std::cell::RefCell<rand::reseeding::ReseedingRng<rand::StdRng, rand::ThreadRngReseeder>>>` cannot be shared between threads safely
|
= help: within `MarkovChain<'static>`, the trait `std::marker::Sync` is not implemented for `std::rc::Rc<std::cell::RefCell<rand::reseeding::ReseedingRng<rand::StdRng, rand::ThreadRngReseeder>>>`
= note: required because it appears within the type `rand::ThreadRng`
= note: required because it appears within the type `MarkovChain<'static>`
= note: required by `lazy_static::lazy::Lazy`
= note: this error originates in a macro outside of the current crate
The code in question. I believe I roughly understand what the error says: the ThreadRng
RNG is not thread safe (not Sync
) and this is required by the voodoo done by the lazy_static!
macro.
Does anybody have a good tip for this situation?
I don't intend to share the MarkovChain
values between threads β I would just like them to carry a bit of state. It doesn't sound like a hard problem