Sorry to say, after playing with this ThreadSafeCache a little bit, I've found some inconvience:
Originally, users would write code like
fn main() {
let cache_manager = Arc::new(Mutex::new(CacheManager::new()));
cache_manager.lock().unwrap().insert(13, String::from("13"));
let mut threads = vec![];
for i in 1..=12 {
// !! natural & classical way to do this !!
let cm = Arc::clone(&cache_manager);
let handle = thread::spawn(move || {
println!("in thread {}, query: {:?}", i, cm.lock().unwrap().query(15))
});
threads.push(handle);
}
threads.into_iter().for_each(|h| h.join().unwrap());
}
This is fine
But after changing to ThreadSafeCache, this way doesn't work...
fn main() {
let cache_manager = ThreadSafeCache::new();
cache_manager.ainsert(13, String::from("13"));
let mut threads = vec![];
for i in 1..=12 {
// !! We cannot call Arc::clone here !!
let cm = Arc::clone(&cache_manager);
let handle = thread::spawn(move || println!("in thread {}, query: {:?}", i, cm.aquery(15)));
threads.push(handle);
}
threads.into_iter().for_each(|h| h.join().unwrap());
}
Would you mind further explaining how you expect users to use this ThreadSafeCache when sticking to std::thread ?
(In last reply, I mistakenly tried with crossbeam::thread::scope and let cm = &cache_manager and passed the compiler)
when impling std::clone::Clone, we're sensing that this object gets a pure clone, yielding an independent object(2 cache in this case!). This may make users confused
This would stop us from impling real Clone in future
by impling a rc_clone method, we explicitly add the rc into method name, which I think would clear users' confuse somehow