mirror of
https://github.com/cargo-bins/cargo-binstall.git
synced 2025-04-24 22:30:03 +00:00
Optimize extract_zip
: Use async_zip::read::stream::ZipFileReader
to avoid temporary file (#590)
* Add new dep async_zip v0.0.9 to binstalk-downloader with features "gzip", "zstd", "xz", "bzip2", "tokio". * Refactor: Simplify `async_extracter::extract_*` API * Refactor: Create newtype wrapper of `ZipError` so that the zip can be upgraded without affecting API of this crate. * Enable feature fs of dep tokio in binstalk-downloader * Rewrite `extract_zip` to use `async_zip::read::stream::ZipFileReader` which avoids writing the zip file to a temporary file and then read it back into memory. * Refactor: Impl new fn `await_on_option` and use it * Optimize `tokio::select!`: Make them biased and check for cancellation first to make cancellation takes effect ASAP. * Rm unused dep zip from binstalk-downloader Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
This commit is contained in:
parent
e6f969245a
commit
3b1a7f2c78
8 changed files with 372 additions and 94 deletions
|
@ -7,7 +7,6 @@ use thiserror::Error as ThisError;
|
|||
use tracing::{debug, instrument};
|
||||
|
||||
pub use binstalk_types::cargo_toml_binstall::PkgFmt;
|
||||
pub use zip::result::ZipError;
|
||||
|
||||
use crate::remote::{Client, Error as RemoteError, Url};
|
||||
|
||||
|
@ -20,6 +19,12 @@ pub use async_tar_visitor::*;
|
|||
mod extracter;
|
||||
mod stream_readable;
|
||||
|
||||
mod zip_extraction;
|
||||
pub use zip_extraction::ZipError;
|
||||
|
||||
mod utils;
|
||||
use utils::await_on_option;
|
||||
|
||||
pub type CancellationFuture = Option<Pin<Box<dyn Future<Output = Result<(), io::Error>> + Send>>>;
|
||||
|
||||
#[derive(Debug, ThisError)]
|
||||
|
@ -112,15 +117,13 @@ impl Download {
|
|||
|
||||
debug!("Downloading and extracting then in-memory processing");
|
||||
|
||||
let ret = if let Some(cancellation_future) = cancellation_future {
|
||||
tokio::select! {
|
||||
res = extract_tar_based_stream_and_visit(stream, fmt, visitor) => res?,
|
||||
res = cancellation_future => {
|
||||
Err(res.err().unwrap_or_else(|| io::Error::from(DownloadError::UserAbort)))?
|
||||
}
|
||||
let ret = tokio::select! {
|
||||
biased;
|
||||
|
||||
res = await_on_option(cancellation_future) => {
|
||||
Err(res.err().unwrap_or_else(|| io::Error::from(DownloadError::UserAbort)))?
|
||||
}
|
||||
} else {
|
||||
extract_tar_based_stream_and_visit(stream, fmt, visitor).await?
|
||||
res = extract_tar_based_stream_and_visit(stream, fmt, visitor) => res?,
|
||||
};
|
||||
|
||||
debug!("Download, extraction and in-memory procession OK");
|
||||
|
@ -145,7 +148,11 @@ impl Download {
|
|||
path: &Path,
|
||||
cancellation_future: CancellationFuture,
|
||||
) -> Result<(), DownloadError> {
|
||||
let stream = this.client.get_stream(this.url).await?;
|
||||
let stream = this
|
||||
.client
|
||||
.get_stream(this.url)
|
||||
.await?
|
||||
.map(|res| res.map_err(DownloadError::from));
|
||||
|
||||
debug!("Downloading and extracting to: '{}'", path.display());
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue