summaryrefslogtreecommitdiff
path: root/cli/npm/managed/resolvers
diff options
context:
space:
mode:
authorDavid Sherret <dsherret@users.noreply.github.com>2024-06-02 21:39:13 -0400
committerGitHub <noreply@github.com>2024-06-03 01:39:13 +0000
commitb1f776adef6f0d0caa0b2badf9fb707cf5efa6e7 (patch)
treedf801e53bb5e43268933d883f049546256ef8e7f /cli/npm/managed/resolvers
parenteda43c46de12ed589fdbe62ba0574887cfbb3574 (diff)
refactor: extract structs for downloading tarballs and npm registry packuments (#24067)
Diffstat (limited to 'cli/npm/managed/resolvers')
-rw-r--r--cli/npm/managed/resolvers/common.rs28
-rw-r--r--cli/npm/managed/resolvers/global.rs26
-rw-r--r--cli/npm/managed/resolvers/local.rs62
-rw-r--r--cli/npm/managed/resolvers/mod.rs19
4 files changed, 85 insertions, 50 deletions
diff --git a/cli/npm/managed/resolvers/common.rs b/cli/npm/managed/resolvers/common.rs
index b010bdd7c..2d540accd 100644
--- a/cli/npm/managed/resolvers/common.rs
+++ b/cli/npm/managed/resolvers/common.rs
@@ -12,7 +12,7 @@ use deno_ast::ModuleSpecifier;
use deno_core::anyhow::Context;
use deno_core::error::AnyError;
use deno_core::futures;
-use deno_core::unsync::spawn;
+use deno_core::futures::StreamExt;
use deno_core::url::Url;
use deno_npm::NpmPackageCacheFolderId;
use deno_npm::NpmPackageId;
@@ -21,7 +21,8 @@ use deno_runtime::deno_fs::FileSystem;
use deno_runtime::deno_node::NodePermissions;
use deno_runtime::deno_node::NodeResolutionMode;
-use super::super::cache::NpmCache;
+use crate::http_util::HttpClient;
+use crate::npm::managed::cache::TarballCache;
/// Part of the resolution that interacts with the file system.
#[async_trait]
@@ -49,7 +50,10 @@ pub trait NpmPackageFsResolver: Send + Sync {
specifier: &ModuleSpecifier,
) -> Result<Option<NpmPackageCacheFolderId>, AnyError>;
- async fn cache_packages(&self) -> Result<(), AnyError>;
+ async fn cache_packages(
+ &self,
+ http_client: &Arc<HttpClient>,
+ ) -> Result<(), AnyError>;
fn ensure_read_permission(
&self,
@@ -126,20 +130,20 @@ impl RegistryReadPermissionChecker {
/// Caches all the packages in parallel.
pub async fn cache_packages(
packages: Vec<NpmResolutionPackage>,
- cache: &Arc<NpmCache>,
+ tarball_cache: &Arc<TarballCache>,
+ http_client: &Arc<HttpClient>,
) -> Result<(), AnyError> {
- let mut handles = Vec::with_capacity(packages.len());
+ let mut futures_unordered = futures::stream::FuturesUnordered::new();
for package in packages {
- let cache = cache.clone();
- let handle = spawn(async move {
- cache.ensure_package(&package.id.nv, &package.dist).await
+ futures_unordered.push(async move {
+ tarball_cache
+ .ensure_package(&package.id.nv, &package.dist, http_client)
+ .await
});
- handles.push(handle);
}
- let results = futures::future::join_all(handles).await;
- for result in results {
+ while let Some(result) = futures_unordered.next().await {
// surface the first error
- result??;
+ result?;
}
Ok(())
}
diff --git a/cli/npm/managed/resolvers/global.rs b/cli/npm/managed/resolvers/global.rs
index cfc57e591..4ffcb251f 100644
--- a/cli/npm/managed/resolvers/global.rs
+++ b/cli/npm/managed/resolvers/global.rs
@@ -20,8 +20,11 @@ use deno_runtime::deno_fs::FileSystem;
use deno_runtime::deno_node::NodePermissions;
use deno_runtime::deno_node::NodeResolutionMode;
+use crate::http_util::HttpClient;
+
use super::super::super::common::types_package_name;
use super::super::cache::NpmCache;
+use super::super::cache::TarballCache;
use super::super::resolution::NpmResolution;
use super::common::cache_packages;
use super::common::NpmPackageFsResolver;
@@ -31,6 +34,7 @@ use super::common::RegistryReadPermissionChecker;
#[derive(Debug)]
pub struct GlobalNpmPackageResolver {
cache: Arc<NpmCache>,
+ tarball_cache: Arc<TarballCache>,
resolution: Arc<NpmResolution>,
system_info: NpmSystemInfo,
registry_read_permission_checker: RegistryReadPermissionChecker,
@@ -38,19 +42,21 @@ pub struct GlobalNpmPackageResolver {
impl GlobalNpmPackageResolver {
pub fn new(
- fs: Arc<dyn FileSystem>,
cache: Arc<NpmCache>,
+ fs: Arc<dyn FileSystem>,
+ tarball_cache: Arc<TarballCache>,
resolution: Arc<NpmResolution>,
system_info: NpmSystemInfo,
) -> Self {
Self {
- cache: cache.clone(),
- resolution,
- system_info,
registry_read_permission_checker: RegistryReadPermissionChecker::new(
fs,
cache.root_folder(),
),
+ cache,
+ tarball_cache,
+ resolution,
+ system_info,
}
}
@@ -123,12 +129,20 @@ impl NpmPackageFsResolver for GlobalNpmPackageResolver {
)
}
- async fn cache_packages(&self) -> Result<(), AnyError> {
+ async fn cache_packages(
+ &self,
+ http_client: &Arc<HttpClient>,
+ ) -> Result<(), AnyError> {
let package_partitions = self
.resolution
.all_system_packages_partitioned(&self.system_info);
- cache_packages(package_partitions.packages, &self.cache).await?;
+ cache_packages(
+ package_partitions.packages,
+ &self.tarball_cache,
+ http_client,
+ )
+ .await?;
// create the copy package folders
for copy in package_partitions.copy_packages {
diff --git a/cli/npm/managed/resolvers/local.rs b/cli/npm/managed/resolvers/local.rs
index f0c2a3f65..5c3b1f15e 100644
--- a/cli/npm/managed/resolvers/local.rs
+++ b/cli/npm/managed/resolvers/local.rs
@@ -14,6 +14,7 @@ use std::path::PathBuf;
use std::sync::Arc;
use crate::cache::CACHE_PERM;
+use crate::http_util::HttpClient;
use crate::npm::cache_dir::mixed_case_package_name_decode;
use crate::util::fs::atomic_write_file;
use crate::util::fs::canonicalize_path_maybe_not_exists_with_fs;
@@ -27,16 +28,15 @@ use deno_ast::ModuleSpecifier;
use deno_core::anyhow::bail;
use deno_core::anyhow::Context;
use deno_core::error::AnyError;
+use deno_core::futures::stream::FuturesUnordered;
+use deno_core::futures::StreamExt;
use deno_core::parking_lot::Mutex;
-use deno_core::unsync::spawn;
-use deno_core::unsync::JoinHandle;
use deno_core::url::Url;
use deno_npm::resolution::NpmResolutionSnapshot;
use deno_npm::NpmPackageCacheFolderId;
use deno_npm::NpmPackageId;
use deno_npm::NpmResolutionPackage;
use deno_npm::NpmSystemInfo;
-use deno_runtime::deno_core::futures;
use deno_runtime::deno_fs;
use deno_runtime::deno_node::NodePermissions;
use deno_runtime::deno_node::NodeResolutionMode;
@@ -48,6 +48,7 @@ use crate::npm::cache_dir::mixed_case_package_name_encode;
use super::super::super::common::types_package_name;
use super::super::cache::NpmCache;
+use super::super::cache::TarballCache;
use super::super::resolution::NpmResolution;
use super::common::NpmPackageFsResolver;
use super::common::RegistryReadPermissionChecker;
@@ -56,10 +57,11 @@ use super::common::RegistryReadPermissionChecker;
/// and resolves packages from it.
#[derive(Debug)]
pub struct LocalNpmPackageResolver {
- fs: Arc<dyn deno_fs::FileSystem>,
cache: Arc<NpmCache>,
+ fs: Arc<dyn deno_fs::FileSystem>,
progress_bar: ProgressBar,
resolution: Arc<NpmResolution>,
+ tarball_cache: Arc<TarballCache>,
root_node_modules_path: PathBuf,
root_node_modules_url: Url,
system_info: NpmSystemInfo,
@@ -68,26 +70,28 @@ pub struct LocalNpmPackageResolver {
impl LocalNpmPackageResolver {
pub fn new(
- fs: Arc<dyn deno_fs::FileSystem>,
cache: Arc<NpmCache>,
+ fs: Arc<dyn deno_fs::FileSystem>,
progress_bar: ProgressBar,
- node_modules_folder: PathBuf,
resolution: Arc<NpmResolution>,
+ tarball_cache: Arc<TarballCache>,
+ node_modules_folder: PathBuf,
system_info: NpmSystemInfo,
) -> Self {
Self {
- fs: fs.clone(),
cache,
+ fs: fs.clone(),
progress_bar,
resolution,
- root_node_modules_url: Url::from_directory_path(&node_modules_folder)
- .unwrap(),
- root_node_modules_path: node_modules_folder.clone(),
- system_info,
+ tarball_cache,
registry_read_permission_checker: RegistryReadPermissionChecker::new(
fs,
- node_modules_folder,
+ node_modules_folder.clone(),
),
+ root_node_modules_url: Url::from_directory_path(&node_modules_folder)
+ .unwrap(),
+ root_node_modules_path: node_modules_folder,
+ system_info,
}
}
@@ -225,11 +229,16 @@ impl NpmPackageFsResolver for LocalNpmPackageResolver {
Ok(get_package_folder_id_from_folder_name(&folder_name))
}
- async fn cache_packages(&self) -> Result<(), AnyError> {
+ async fn cache_packages(
+ &self,
+ http_client: &Arc<HttpClient>,
+ ) -> Result<(), AnyError> {
sync_resolution_with_fs(
&self.resolution.snapshot(),
&self.cache,
+ http_client,
&self.progress_bar,
+ &self.tarball_cache,
&self.root_node_modules_path,
&self.system_info,
)
@@ -251,7 +260,9 @@ impl NpmPackageFsResolver for LocalNpmPackageResolver {
async fn sync_resolution_with_fs(
snapshot: &NpmResolutionSnapshot,
cache: &Arc<NpmCache>,
+ http_client: &Arc<HttpClient>,
progress_bar: &ProgressBar,
+ tarball_cache: &Arc<TarballCache>,
root_node_modules_dir_path: &Path,
system_info: &NpmSystemInfo,
) -> Result<(), AnyError> {
@@ -288,8 +299,7 @@ async fn sync_resolution_with_fs(
// node_modules/.deno/<package_folder_id_folder_name>/node_modules/<package_name>
let package_partitions =
snapshot.all_system_packages_partitioned(system_info);
- let mut handles: Vec<JoinHandle<Result<(), AnyError>>> =
- Vec::with_capacity(package_partitions.packages.len());
+ let mut cache_futures = FuturesUnordered::new();
let mut newest_packages_by_name: HashMap<&String, &NpmResolutionPackage> =
HashMap::with_capacity(package_partitions.packages.len());
let bin_entries = Arc::new(Mutex::new(bin_entries::BinEntries::new()));
@@ -317,21 +327,19 @@ async fn sync_resolution_with_fs(
// are forced to be recreated
setup_cache.remove_dep(&package_folder_name);
- let pb = progress_bar.clone();
- let cache = cache.clone();
- let package = package.clone();
let bin_entries_to_setup = bin_entries.clone();
- let handle = spawn(async move {
- cache.ensure_package(&package.id.nv, &package.dist).await?;
- let pb_guard = pb.update_with_prompt(
+ cache_futures.push(async move {
+ tarball_cache
+ .ensure_package(&package.id.nv, &package.dist, http_client)
+ .await?;
+ let pb_guard = progress_bar.update_with_prompt(
ProgressMessagePrompt::Initialize,
&package.id.nv.to_string(),
);
let sub_node_modules = folder_path.join("node_modules");
let package_path =
join_package_name(&sub_node_modules, &package.id.nv.name);
- let cache_folder =
- cache.package_folder_for_name_and_version(&package.id.nv);
+ let cache_folder = cache.package_folder_for_nv(&package.id.nv);
deno_core::unsync::spawn_blocking({
let package_path = package_path.clone();
@@ -353,15 +361,13 @@ async fn sync_resolution_with_fs(
// finally stop showing the progress bar
drop(pb_guard); // explicit for clarity
- Ok(())
+ Ok::<_, AnyError>(())
});
- handles.push(handle);
}
}
- let results = futures::future::join_all(handles).await;
- for result in results {
- result??; // surface the first error
+ while let Some(result) = cache_futures.next().await {
+ result?; // surface the first error
}
// 2. Create any "copy" packages, which are used for peer dependencies
diff --git a/cli/npm/managed/resolvers/mod.rs b/cli/npm/managed/resolvers/mod.rs
index d5472344a..5f0343805 100644
--- a/cli/npm/managed/resolvers/mod.rs
+++ b/cli/npm/managed/resolvers/mod.rs
@@ -7,6 +7,7 @@ mod local;
use std::path::PathBuf;
use std::sync::Arc;
+use deno_npm::npm_rc::ResolvedNpmRc;
use deno_npm::NpmSystemInfo;
use deno_runtime::deno_fs::FileSystem;
@@ -18,28 +19,38 @@ use self::global::GlobalNpmPackageResolver;
use self::local::LocalNpmPackageResolver;
use super::cache::NpmCache;
+use super::cache::TarballCache;
use super::resolution::NpmResolution;
pub fn create_npm_fs_resolver(
fs: Arc<dyn FileSystem>,
- cache: Arc<NpmCache>,
+ npm_cache: Arc<NpmCache>,
+ npm_rc: Arc<ResolvedNpmRc>,
progress_bar: &ProgressBar,
resolution: Arc<NpmResolution>,
maybe_node_modules_path: Option<PathBuf>,
system_info: NpmSystemInfo,
) -> Arc<dyn NpmPackageFsResolver> {
+ let tarball_cache = Arc::new(TarballCache::new(
+ npm_cache.clone(),
+ fs.clone(),
+ npm_rc,
+ progress_bar.clone(),
+ ));
match maybe_node_modules_path {
Some(node_modules_folder) => Arc::new(LocalNpmPackageResolver::new(
+ npm_cache,
fs,
- cache,
progress_bar.clone(),
- node_modules_folder,
resolution,
+ tarball_cache,
+ node_modules_folder,
system_info,
)),
None => Arc::new(GlobalNpmPackageResolver::new(
+ npm_cache,
fs,
- cache,
+ tarball_cache,
resolution,
system_info,
)),