Newbie question here - new to both Rust and system-level languages so would very much appreciate some help.
Use case is that I'm generating a map of financial bars from csv files of ticks and serialising to disk.
I'm looking to make pluggable generators for different types of bar.
My naïve plugin has a single trait:
pub trait Generator {
// Process a tick and return any new bars
fn next(&self, tick: Tick, tick_dt: NaiveDateTime) -> Option<BTreeMap<i64, Bar>>;
}
To speed up the process, the generator runs each financial symbol in parallel:
use rayon::prelude::*
fn run_generator(
generator: Box<dyn Generator>,
symbols: &Vec<Symbol>,
start_year: u16,
end_year: u16) {
symbols.par_iter().for_each(|symbol| {
for year in start_year..=end_year {
...
let option = generator.next(tick, tick_dt);
}
}
}
The par_iter().for_each
fails to compile because the Generator trait cannot be shared between threads as the Sync trait is not implemented.
The problem appears to be that any borrowing is seen as unsafe, but I have to pass a borrowed &self
.
So how are trait objects used within a parallel loop? This is a pattern I was planning to use quite extensively in the app, so I'd appreciate any pointers (pun intended) towards a practical solution.