try_get_with_by_ref always triggers init future #206
-
I'm having some trouble with
This code: let key: PathBuf = self.path.clone();
let metadata = self
.mdcache
.try_get_with_by_ref(
&key,
async {
tracing::debug!(
"mdcache miss ({})",
if self.mdcache.contains_key(&key) {
"NOT expected"
} else {
"expected"
},
);
self.file.read_metadata()
}
.await,
)
.await
.unwrap(); Is producing this kind of output consistently -- the only "expected" miss is the first access. For all of the following accesses,
The following code works as expected, but loses the guarantee of a single in-flight init task for a given key: match self.mdcache.get(&self.path) {
Some(md) => Ok(md),
None => {
tracing::debug!("mdcache miss");
let md = self.file.read_metadata().await?;
self.mdcache.insert(self.path.clone(), md.clone()).await;
Ok(md)
}
} Am I misunderstanding how |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
Pretty sure this is a cache implementation issue. Created #208 |
Beta Was this translation helpful? Give feedback.
-
Thank you for reporting. I reviewed your original code, and I believe you have an extra let metadata = self
.mdcache
.try_get_with_by_ref(
&key,
async {
tracing::debug!(
"mdcache miss ({})",
if self.mdcache.contains_key(&key) {
"NOT expected"
} else {
"expected"
},
);
self.file.read_metadata()
}
// Please remove this await. This causes the async block above executed
// unconditionally _before_ being passed to try_get_with_by_ref().
.await,
)
.await
.unwrap(); |
Beta Was this translation helpful? Give feedback.
Thank you for reporting. I reviewed your original code, and I believe you have an extra
.await
, which causes the async block executed unconditionally before being passed totry_get_with_by_ref()
. Please remove it.