fix: don't block executor with integrity checking

This commit is contained in:
Jakub Koralewski 2025-11-20 16:49:08 +00:00
parent 66eae4b78f
commit 82e29a541c
3 changed files with 20 additions and 6 deletions

View File

@ -118,15 +118,23 @@ pub fn read(cache: &Path, sri: &Integrity) -> Result<Vec<u8>> {
} }
#[cfg(any(feature = "async-std", feature = "tokio"))] #[cfg(any(feature = "async-std", feature = "tokio"))]
pub async fn read_async<'a>(cache: &'a Path, sri: &'a Integrity) -> Result<Vec<u8>> { pub async fn read_async<'c, 's>(cache: &'c Path, sri: Integrity) -> Result<Vec<u8>> {
let cpath = path::content_path(cache, sri); // let cache = cache.to_path_buf();
let cpath = path::content_path(&cache, &sri);
let ret = crate::async_lib::read(&cpath).await.with_context(|| { let ret = crate::async_lib::read(&cpath).await.with_context(|| {
format!( format!(
"Failed to read contents for file at {}", "Failed to read contents for file at {}",
path::content_path(cache, sri).display() path::content_path(&cache, &sri).display()
) )
})?; })?;
sri.check(&ret)?; let integrity_check = move || {
sri.check(&ret)?;
Ok::<_, ssri::Error>(ret)
};
#[cfg(feature = "tokio")]
let ret = tokio::task::spawn_blocking(integrity_check).await??;
#[cfg(feature = "async-std")]
let ret = async_std::task::spawn_blocking(integrity_check).await?;
Ok(ret) Ok(ret)
} }

View File

@ -31,6 +31,12 @@ pub enum Error {
#[error(transparent)] #[error(transparent)]
#[diagnostic(code(cacache::integrity_error), url(docsrs))] #[diagnostic(code(cacache::integrity_error), url(docsrs))]
IntegrityError(#[from] ssri::Error), IntegrityError(#[from] ssri::Error),
/// Returned when a Tokio join error occured.
#[cfg(feature="tokio")]
#[error(transparent)]
#[diagnostic(code(cacache::tokio_joinerror), url(docsrs))]
TokioJoinError(#[from] tokio::task::JoinError)
} }
/// The result type returned by calls to this library /// The result type returned by calls to this library

View File

@ -159,7 +159,7 @@ where
{ {
async fn inner(cache: &Path, key: &str) -> Result<Vec<u8>> { async fn inner(cache: &Path, key: &str) -> Result<Vec<u8>> {
if let Some(entry) = index::find_async(cache, key).await? { if let Some(entry) = index::find_async(cache, key).await? {
read_hash(cache, &entry.integrity).await read_hash(cache, entry.integrity).await
} else { } else {
Err(Error::EntryNotFound(cache.to_path_buf(), key.into())) Err(Error::EntryNotFound(cache.to_path_buf(), key.into()))
} }
@ -183,7 +183,7 @@ where
/// } /// }
/// ``` /// ```
#[cfg(any(feature = "async-std", feature = "tokio"))] #[cfg(any(feature = "async-std", feature = "tokio"))]
pub async fn read_hash<P>(cache: P, sri: &Integrity) -> Result<Vec<u8>> pub async fn read_hash<P>(cache: P, sri: Integrity) -> Result<Vec<u8>>
where where
P: AsRef<Path>, P: AsRef<Path>,
{ {