我目前正在实现一个多客户端键值存储(如 redis 或 memcached),它允许客户端获得对存储的独占访问权限。
现在我遇到的问题是,当从共享存储中获取值时,它可以由 RwLockWriteGoard (当独占访问处于活动状态时)或 RwLockReadGuard 保护时不受保护。
我没有找到一种方法将存储保存在变量中,以便稍后以一种不关心它是否受读或写保护保护的方式对其执行操作。
这是我目前使用的简化解决方案。
// Assume Store is like this
let store = Arc::new(RwLock::new(HashMap::new()));
// --snip--
let mut exclusive_access: Option<RwLockWriteGuard<HashMap<String, String>>> = None;
while !is_finished {
// --snip--
let response = match parse_command(&command) {
Command::Get(key) => {
let read_result = match exclusive_access {
Some(exclusive_store) => match exclusive_store.get(&key) {
Some(x) => Some(x.clone()),
None => None,
},
None => match store.read().unwrap().get(&key) {
Some(x) => Some(x.clone()),
None => None,
},
};
// simplified
read_result
}
// --snip--
};
if gain_exclusive_access {
exclusive_access = Some(store.write().unwrap());
} else {
exclusive_access = None;
}
}
如果可能的话,我想把 Command::Get(key) arm 写成这样:
let store = match exclusive_access {
Some(store) => store,
None => store.read().unwrap()
};
store.get(&key)
但这不起作用,因为该匹配的两个臂返回不同的类型(RwLockWriteGuard 和 RwLockReadGuard)。
有没有办法解决这个问题,我太盲目了,看不到?