Skip to content

Commit 57ac392

Browse files
committed
Auto merge of #6005 - alexcrichton:download-parallel, r=ehuss
Download crates in parallel with HTTP/2 This PR revives some of the work of #5161 by refactoring Cargo to make it much easier to add parallel downloads, and then it does so with the `curl` crate's new `http2` feature to compile `nghttp2` has a backend. The primary refactoring done here is to remove the concept of "download this one package" deep within a `Source`. Instead a `Source` still has a `download` method but it's considered to be largely non-blocking. If a crate needs to be downloaded it immediately returns information as to such. The `PackageSet` abstraction is now a central location for all parallel downloads, and all users of it have been refactored to be amenable to parallel downloads, when added. Many more details are in the commits...
2 parents a22f54a + f4dcb5c commit 57ac392

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1248
-432
lines changed

Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,11 @@ path = "src/cargo/lib.rs"
1818

1919
[dependencies]
2020
atty = "0.2"
21+
bytesize = "1.0"
2122
crates-io = { path = "src/crates-io", version = "0.20" }
2223
crossbeam-utils = "0.5"
2324
crypto-hash = "0.3.1"
24-
curl = "0.4.13"
25+
curl = { version = "0.4.17", features = ['http2'] }
2526
env_logger = "0.5.11"
2627
failure = "0.1.2"
2728
filetime = "0.2"

src/cargo/core/compiler/build_context/mod.rs

+1-18
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::str;
55

66
use core::profiles::Profiles;
77
use core::{Dependency, Workspace};
8-
use core::{Package, PackageId, PackageSet, Resolve};
8+
use core::{PackageId, PackageSet, Resolve};
99
use util::errors::CargoResult;
1010
use util::{profile, Cfg, CfgExpr, Config, Rustc};
1111

@@ -107,11 +107,6 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
107107
platform.matches(name, info.cfg())
108108
}
109109

110-
/// Gets a package for the given package id.
111-
pub fn get_package(&self, id: &PackageId) -> CargoResult<&'a Package> {
112-
self.packages.get(id)
113-
}
114-
115110
/// Get the user-specified linker for a particular host or target
116111
pub fn linker(&self, kind: Kind) -> Option<&Path> {
117112
self.target_config(kind).linker.as_ref().map(|s| s.as_ref())
@@ -198,18 +193,6 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
198193
pub fn extra_args_for(&self, unit: &Unit<'a>) -> Option<&Vec<String>> {
199194
self.extra_compiler_args.get(unit)
200195
}
201-
202-
/// Return the list of filenames read by cargo to generate the BuildContext
203-
/// (all Cargo.toml, etc).
204-
pub fn inputs(&self) -> CargoResult<Vec<PathBuf>> {
205-
let mut inputs = Vec::new();
206-
for id in self.packages.package_ids() {
207-
let pkg = self.get_package(id)?;
208-
inputs.push(pkg.manifest_path().to_path_buf());
209-
}
210-
inputs.sort();
211-
Ok(inputs)
212-
}
213196
}
214197

215198
/// Information required to build for a target

src/cargo/core/compiler/context/mod.rs

+28-2
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ pub struct Context<'a, 'cfg: 'a> {
9999
primary_packages: HashSet<&'a PackageId>,
100100
unit_dependencies: HashMap<Unit<'a>, Vec<Unit<'a>>>,
101101
files: Option<CompilationFiles<'a, 'cfg>>,
102+
package_cache: HashMap<&'a PackageId, &'a Package>,
102103
}
103104

104105
impl<'a, 'cfg> Context<'a, 'cfg> {
@@ -133,6 +134,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
133134
primary_packages: HashSet::new(),
134135
unit_dependencies: HashMap::new(),
135136
files: None,
137+
package_cache: HashMap::new(),
136138
})
137139
}
138140

@@ -165,7 +167,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
165167
queue.execute(&mut self, &mut plan)?;
166168

167169
if build_plan {
168-
plan.set_inputs(self.bcx.inputs()?);
170+
plan.set_inputs(self.inputs()?);
169171
plan.output_plan();
170172
}
171173

@@ -326,7 +328,12 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
326328
};
327329
self.primary_packages.extend(units.iter().map(|u| u.pkg.package_id()));
328330

329-
build_unit_dependencies(units, self.bcx, &mut self.unit_dependencies)?;
331+
build_unit_dependencies(
332+
units,
333+
self.bcx,
334+
&mut self.unit_dependencies,
335+
&mut self.package_cache,
336+
)?;
330337
self.build_used_in_plugin_map(units)?;
331338
let files = CompilationFiles::new(
332339
units,
@@ -495,6 +502,25 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
495502
pub fn is_primary_package(&self, unit: &Unit<'a>) -> bool {
496503
self.primary_packages.contains(unit.pkg.package_id())
497504
}
505+
506+
/// Gets a package for the given package id.
507+
pub fn get_package(&self, id: &PackageId) -> CargoResult<&'a Package> {
508+
self.package_cache.get(id)
509+
.cloned()
510+
.ok_or_else(|| format_err!("failed to find {}", id))
511+
}
512+
513+
/// Return the list of filenames read by cargo to generate the BuildContext
514+
/// (all Cargo.toml, etc).
515+
pub fn inputs(&self) -> CargoResult<Vec<PathBuf>> {
516+
let mut inputs = Vec::new();
517+
for id in self.bcx.packages.package_ids() {
518+
let pkg = self.get_package(id)?;
519+
inputs.push(pkg.manifest_path().to_path_buf());
520+
}
521+
inputs.sort();
522+
Ok(inputs)
523+
}
498524
}
499525

500526
#[derive(Default)]

0 commit comments

Comments
 (0)