Skip to content

Commit e0afb0f

Browse files
authored
Merge pull request #10064 from eth3lbert/async-tarball
Migrate `crates_io_tarball` to async/await
2 parents db4f944 + 67b5de0 commit e0afb0f

File tree

7 files changed

+165
-93
lines changed

7 files changed

+165
-93
lines changed

Cargo.lock

Lines changed: 43 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/crates_io_tarball/Cargo.toml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,29 @@ edition = "2021"
88
workspace = true
99

1010
[features]
11-
builder = []
11+
builder = ["dep:flate2", "dep:tar"]
1212

1313
[dependencies]
1414
cargo-manifest = "=0.16.1"
15-
flate2 = "=1.0.35"
15+
flate2 = { version = "=1.0.35", optional = true }
1616
serde = { version = "=1.0.215", features = ["derive"] }
1717
serde_json = "=1.0.133"
18-
tar = "=0.4.43"
18+
tar = { version = "=0.4.43", optional = true }
1919
thiserror = "=2.0.3"
2020
tracing = "=0.1.40"
21+
tokio = { version = "=1.41.1", features = ["io-util", "macros", "rt-multi-thread"] }
22+
async-compression = { version = "=0.4.18", default-features = false, features = ["gzip", "tokio"] }
23+
krata-tokio-tar = "=0.4.2"
24+
futures-util = "=0.3.31"
2125

2226
[dev-dependencies]
2327
anyhow = "=1.0.93"
2428
claims = "=0.8.0"
2529
clap = { version = "=4.5.21", features = ["derive", "unicode", "wrap_help"] }
30+
flate2 = { version = "=1.0.35" }
2631
indicatif = { version = "=0.17.9", features = ["rayon"] }
2732
insta = "=1.41.1"
2833
rayon = "=1.10.0"
34+
tar = { version = "=0.4.43" }
2935
tracing-subscriber = { version = "=0.3.18", features = ["env-filter"] }
3036
walkdir = "=2.5.0"

crates/crates_io_tarball/examples/check_all_crates.rs

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
use anyhow::anyhow;
22
use clap::Parser;
33
use crates_io_tarball::process_tarball;
4-
use indicatif::{ParallelProgressIterator, ProgressBar, ProgressStyle};
4+
use futures_util::{stream, StreamExt};
5+
use indicatif::{ParallelProgressIterator, ProgressBar, ProgressIterator, ProgressStyle};
56
use rayon::prelude::*;
6-
use std::fs::File;
77
use std::path::{Path, PathBuf};
8+
use tokio::fs::File;
89
use tracing::{debug, info, warn};
910
use tracing_subscriber::filter::LevelFilter;
1011
use tracing_subscriber::EnvFilter;
@@ -17,7 +18,8 @@ pub struct Options {
1718
path: PathBuf,
1819
}
1920

20-
fn main() -> anyhow::Result<()> {
21+
#[tokio::main]
22+
async fn main() -> anyhow::Result<()> {
2123
setup_tracing();
2224

2325
let options = Options::parse();
@@ -51,27 +53,30 @@ fn main() -> anyhow::Result<()> {
5153
ProgressStyle::with_template("{bar:60} ({pos}/{len}, ETA {eta}) {wide_msg}").unwrap(),
5254
);
5355

54-
paths
55-
.par_iter()
56-
.progress_with(pb.clone())
57-
.for_each(|path| process_path(path, &pb));
56+
stream::iter(paths.iter().progress_with(pb.clone()))
57+
.for_each_concurrent(None, |path| {
58+
let pb = pb.clone();
59+
async move { process_path(path, &pb).await }
60+
})
61+
.await;
5862

5963
Ok(())
6064
}
6165

62-
fn process_path(path: &Path, pb: &ProgressBar) {
63-
let file =
64-
File::open(path).map_err(|error| pb.suspend(|| warn!(%error, "Failed to read crate file")));
66+
async fn process_path(path: &Path, pb: &ProgressBar) {
67+
let file = File::open(path)
68+
.await
69+
.map_err(|error| pb.suspend(|| warn!(%error, "Failed to read crate file")));
6570

66-
let Ok(file) = file else {
71+
let Ok(mut file) = file else {
6772
return;
6873
};
6974

7075
let path_no_ext = path.with_extension("");
7176
let pkg_name = path_no_ext.file_name().unwrap().to_string_lossy();
7277
pb.set_message(format!("{pkg_name}"));
7378

74-
let result = process_tarball(&pkg_name, &file, u64::MAX);
79+
let result = process_tarball(&pkg_name, &mut file, u64::MAX).await;
7580
pb.suspend(|| match result {
7681
Ok(result) => debug!(%pkg_name, path = %path.display(), ?result),
7782
Err(error) => warn!(%pkg_name, path = %path.display(), %error, "Failed to process tarball"),

crates/crates_io_tarball/examples/read_file.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use anyhow::{anyhow, Context};
22
use clap::Parser;
33
use crates_io_tarball::process_tarball;
4-
use std::fs::File;
54
use std::path::PathBuf;
5+
use tokio::fs::File;
66
use tracing_subscriber::filter::LevelFilter;
77
use tracing_subscriber::EnvFilter;
88

@@ -15,7 +15,8 @@ pub struct Options {
1515
path: PathBuf,
1616
}
1717

18-
fn main() -> anyhow::Result<()> {
18+
#[tokio::main]
19+
async fn main() -> anyhow::Result<()> {
1920
setup_tracing();
2021

2122
let options = Options::parse();
@@ -25,13 +26,14 @@ fn main() -> anyhow::Result<()> {
2526
return Err(anyhow!("`{}` not found or not a file", path.display()));
2627
}
2728

28-
let file = File::open(&path).context("Failed to read tarball")?;
29+
let mut file = File::open(&path).await.context("Failed to read tarball")?;
2930

3031
let path_no_ext = path.with_extension("");
3132
let pkg_name = path_no_ext.file_name().unwrap().to_string_lossy();
3233

33-
let result =
34-
process_tarball(&pkg_name, &file, u64::MAX).context("Failed to process tarball")?;
34+
let result = process_tarball(&pkg_name, &mut file, u64::MAX)
35+
.await
36+
.context("Failed to process tarball")?;
3537

3638
println!("{result:#?}");
3739

0 commit comments

Comments
 (0)