Propagate cancellation errors in OnceMap (#1032)

## Summary

Ensures that if an operation is cancelled in one thread, we propagate it
to others rather than panicking.

Related to https://github.com/astral-sh/puffin/issues/1005.
This commit is contained in:
Charlie Marsh 2024-01-22 09:00:21 -05:00 committed by GitHub
parent db0c76c4ba
commit e09a51653e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 25 additions and 10 deletions

View file

@ -14,4 +14,5 @@ workspace = true
[dependencies]
rustc-hash = { workspace = true }
thiserror = { workspace = true }
waitmap = { workspace = true }

View file

@ -54,14 +54,14 @@ impl<K: Eq + Hash, V> OnceMap<K, V> {
/// Wait for the result of a job that is running.
///
/// Will hang if [`OnceMap::done`] isn't called for this key.
pub async fn wait<Q: ?Sized + Hash + Eq>(&self, key: &Q) -> Ref<'_, K, V, RandomState>
pub async fn wait<Q: ?Sized + Hash + Eq>(
&self,
key: &Q,
) -> Result<Ref<'_, K, V, RandomState>, Error>
where
K: Borrow<Q> + for<'a> From<&'a Q>,
{
self.wait_map
.wait(key)
.await
.expect("This operation is never cancelled")
self.wait_map.wait(key).await.ok_or(Error::Canceled)
}
/// Return the result of a previous job, if any.
@ -88,3 +88,9 @@ impl<K: Eq + Hash + Clone, V> Default for OnceMap<K, V> {
}
}
}
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("The operation was canceled")]
Canceled,
}