I'm getting a static lifetime error when trying to send/receive information using mpsc
channel framework.
I thought I was careful in making sure that each thread owns "its share" and when completed, transfers that ownership.
Clearly, I'm missing something. I have read other posts, but can't see "it". Any ideas would be greatly appreciated.
pub fn run(&mut self) -> &'a mut Inspector<'_> {
let (tx, rx): (Sender<FieldCounters>, Receiver<FieldCounters>) = mpsc::channel();
let mut workers = Vec::with_capacity(self.num_workers());
// ⏰ usize, copied when moved
// use single value to set the number of counters for each thread
let num_fields = self.header.as_ref().unwrap().len();
let num_records = self.in_memory_index.as_ref().unwrap().len();
let job_size = utils::job_size(num_records as usize, self.num_workers());
for id in 0..self.num_workers() {
let thread_tx = tx.clone();
// ✨
let worker = thread::spawn(move || {
// Instantiate what is mine and mine only!
let mut field_counters = FieldCounters::new(num_fields);
let mut reader = match reader_at_pos(
self.filepath.as_ref().unwrap(),
(id * job_size) as u64,
self.in_memory_index.as_ref().unwrap(),
) {
Err(e) => {
panic!("Reader failed for thread: {}", id)
}
Ok(reader) => reader,
};
// 🧮 count_fields_in_file
// side-effect of updating the field_counters
match count_fields_in_file(&mut field_counters, &mut reader, Some(job_size)) {
Err(e) => println!("Counter failed for thread: {}", id),
Ok(_) => println!(
"Counter success for thread: {}; last record pos: {}",
&id,
(job_size * id)
),
};
thread_tx.send(field_counters).unwrap();
});
// collection of active workers (worker: JoinHandle)
workers.push(worker);
}
println!(
"Inspector counts starting at: {:?}",
self.field_counters.as_ref().unwrap()
);
[0..self.num_workers()]
.iter()
.for_each(|_| match rx.recv() {
Err(e) => println!("{}", e),
Ok(counts) => self.field_counters.as_mut().unwrap().combine(&counts),
});
for worker in workers {
worker.join().expect("oops! the worker thread panicked");
}
self
}
And the error:
error[E0477]: the type `[closure@src/inspector.rs:140:40: 167:14]` does not fulfill the required lifetime
--> src/inspector.rs:140:26
|
140 | let worker = thread::spawn(move || {
| ^^^^^^^^^^^^^
|
= note: type must satisfy the static lifetime
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> src/inspector.rs:140:40
|
140 | let worker = thread::spawn(move || {
| ________________________________________^
141 | | // Instantiate what is mine and mine only!
142 | | let mut field_counters = FieldCounters::new(num_fields);
143 | | let mut reader = match reader_at_pos(
... |
166 | | thread_tx.send(field_counters).unwrap();
167 | | });
| |_____________^
|
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the impl at 36:6...
--> src/inspector.rs:36:6
|
36 | impl<'a> Inspector<'a> {
| ^^
note: ...so that the reference type `&mut Inspector<'a>` does not outlive the data it points at
--> src/inspector.rs:140:26
|
140 | let worker = thread::spawn(move || {
| ^^^^^^^^^^^^^
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that the type `[closure@src/inspector.rs:140:40: 167:14]` will meet its required lifetime bounds
--> src/inspector.rs:140:26
|
140 | let worker = thread::spawn(move || {
| ^^^^^^^^^^^^^