mirror of
https://github.com/denoland/deno.git
synced 2025-08-04 10:59:13 +00:00
fix(npm): use an http client with connection pool (#16705)
Should make downloading npm packages faster and more reliable.
This commit is contained in:
parent
6962808f4b
commit
763d492ed6
8 changed files with 454 additions and 422 deletions
|
@ -50,7 +50,6 @@ use super::parent_process_checker;
|
|||
use super::performance::Performance;
|
||||
use super::refactor;
|
||||
use super::registries::ModuleRegistry;
|
||||
use super::registries::ModuleRegistryOptions;
|
||||
use super::testing;
|
||||
use super::text;
|
||||
use super::tsc;
|
||||
|
@ -65,10 +64,13 @@ use crate::args::FmtConfig;
|
|||
use crate::args::LintConfig;
|
||||
use crate::args::TsConfig;
|
||||
use crate::deno_dir;
|
||||
use crate::deno_dir::DenoDir;
|
||||
use crate::file_fetcher::get_root_cert_store;
|
||||
use crate::file_fetcher::get_source_from_data_url;
|
||||
use crate::file_fetcher::CacheSetting;
|
||||
use crate::fs_util;
|
||||
use crate::graph_util::graph_valid;
|
||||
use crate::http_util::HttpClient;
|
||||
use crate::npm::NpmCache;
|
||||
use crate::npm::NpmPackageResolver;
|
||||
use crate::npm::RealNpmRegistryApi;
|
||||
|
@ -235,17 +237,43 @@ impl LanguageServer {
|
|||
}
|
||||
}
|
||||
|
||||
fn create_lsp_npm_resolver(
|
||||
dir: &DenoDir,
|
||||
http_client: HttpClient,
|
||||
) -> NpmPackageResolver {
|
||||
let registry_url = RealNpmRegistryApi::default_url();
|
||||
// Use an "only" cache setting in order to make the
|
||||
// user do an explicit "cache" command and prevent
|
||||
// the cache from being filled with lots of packages while
|
||||
// the user is typing.
|
||||
let cache_setting = CacheSetting::Only;
|
||||
let progress_bar = ProgressBar::default();
|
||||
let npm_cache = NpmCache::from_deno_dir(
|
||||
dir,
|
||||
cache_setting.clone(),
|
||||
http_client.clone(),
|
||||
progress_bar.clone(),
|
||||
);
|
||||
let api = RealNpmRegistryApi::new(
|
||||
registry_url,
|
||||
npm_cache.clone(),
|
||||
cache_setting,
|
||||
http_client,
|
||||
progress_bar,
|
||||
);
|
||||
NpmPackageResolver::new(npm_cache, api, false, None)
|
||||
}
|
||||
|
||||
impl Inner {
|
||||
fn new(client: Client) -> Self {
|
||||
let maybe_custom_root = env::var("DENO_DIR").map(String::into).ok();
|
||||
let dir = deno_dir::DenoDir::new(maybe_custom_root)
|
||||
.expect("could not access DENO_DIR");
|
||||
let module_registries_location = dir.root.join(REGISTRIES_PATH);
|
||||
let module_registries = ModuleRegistry::new(
|
||||
&module_registries_location,
|
||||
ModuleRegistryOptions::default(),
|
||||
)
|
||||
.expect("could not create module registries");
|
||||
let http_client = HttpClient::new(None, None).unwrap();
|
||||
let module_registries =
|
||||
ModuleRegistry::new(&module_registries_location, http_client.clone())
|
||||
.unwrap();
|
||||
let location = dir.root.join(CACHE_PATH);
|
||||
let documents = Documents::new(&location);
|
||||
let cache_metadata = cache::CacheMetadata::new(&location);
|
||||
|
@ -258,25 +286,7 @@ impl Inner {
|
|||
ts_server.clone(),
|
||||
);
|
||||
let assets = Assets::new(ts_server.clone());
|
||||
let registry_url = RealNpmRegistryApi::default_url();
|
||||
// Use an "only" cache setting in order to make the
|
||||
// user do an explicit "cache" command and prevent
|
||||
// the cache from being filled with lots of packages while
|
||||
// the user is typing.
|
||||
let cache_setting = CacheSetting::Only;
|
||||
let progress_bar = ProgressBar::default();
|
||||
let npm_cache = NpmCache::from_deno_dir(
|
||||
&dir,
|
||||
cache_setting.clone(),
|
||||
progress_bar.clone(),
|
||||
);
|
||||
let api = RealNpmRegistryApi::new(
|
||||
registry_url,
|
||||
npm_cache.clone(),
|
||||
cache_setting,
|
||||
progress_bar,
|
||||
);
|
||||
let npm_resolver = NpmPackageResolver::new(npm_cache, api, false, None);
|
||||
let npm_resolver = create_lsp_npm_resolver(&dir, http_client);
|
||||
|
||||
Self {
|
||||
assets,
|
||||
|
@ -498,36 +508,48 @@ impl Inner {
|
|||
None
|
||||
};
|
||||
if self.maybe_cache_path != maybe_cache_path {
|
||||
let maybe_custom_root = maybe_cache_path
|
||||
.clone()
|
||||
.or_else(|| env::var("DENO_DIR").map(String::into).ok());
|
||||
let dir = deno_dir::DenoDir::new(maybe_custom_root)?;
|
||||
let module_registries_location = dir.root.join(REGISTRIES_PATH);
|
||||
let workspace_settings = self.config.get_workspace_settings();
|
||||
let maybe_root_path = self
|
||||
.config
|
||||
.root_uri
|
||||
.as_ref()
|
||||
.and_then(|uri| fs_util::specifier_to_file_path(uri).ok());
|
||||
self.module_registries = ModuleRegistry::new(
|
||||
&module_registries_location,
|
||||
ModuleRegistryOptions {
|
||||
maybe_root_path,
|
||||
maybe_ca_stores: workspace_settings.certificate_stores.clone(),
|
||||
maybe_ca_file: workspace_settings.tls_certificate.clone(),
|
||||
unsafely_ignore_certificate_errors: workspace_settings
|
||||
.unsafely_ignore_certificate_errors,
|
||||
},
|
||||
)?;
|
||||
self.module_registries_location = module_registries_location;
|
||||
let location = dir.root.join(CACHE_PATH);
|
||||
self.documents.set_location(&location);
|
||||
self.cache_metadata.set_location(&location);
|
||||
self.maybe_cache_path = maybe_cache_path;
|
||||
self.recreate_http_client_and_dependents(maybe_cache_path)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Recreates the http client and all dependent structs.
|
||||
fn recreate_http_client_and_dependents(
|
||||
&mut self,
|
||||
new_cache_path: Option<PathBuf>,
|
||||
) -> Result<(), AnyError> {
|
||||
let maybe_custom_root = new_cache_path
|
||||
.clone()
|
||||
.or_else(|| env::var("DENO_DIR").map(String::into).ok());
|
||||
let dir = deno_dir::DenoDir::new(maybe_custom_root)?;
|
||||
let workspace_settings = self.config.get_workspace_settings();
|
||||
let maybe_root_path = self
|
||||
.config
|
||||
.root_uri
|
||||
.as_ref()
|
||||
.and_then(|uri| fs_util::specifier_to_file_path(uri).ok());
|
||||
let root_cert_store = Some(get_root_cert_store(
|
||||
maybe_root_path,
|
||||
workspace_settings.certificate_stores.clone(),
|
||||
workspace_settings.tls_certificate.clone(),
|
||||
)?);
|
||||
let client = HttpClient::new(
|
||||
root_cert_store,
|
||||
workspace_settings.unsafely_ignore_certificate_errors,
|
||||
)?;
|
||||
let module_registries_location = dir.root.join(REGISTRIES_PATH);
|
||||
self.module_registries =
|
||||
ModuleRegistry::new(&module_registries_location, client.clone())?;
|
||||
self.module_registries_location = module_registries_location;
|
||||
self.npm_resolver = create_lsp_npm_resolver(&dir, client);
|
||||
// update the cache path
|
||||
let location = dir.root.join(CACHE_PATH);
|
||||
self.documents.set_location(&location);
|
||||
self.cache_metadata.set_location(&location);
|
||||
self.maybe_cache_path = new_cache_path;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn update_import_map(&mut self) -> Result<(), AnyError> {
|
||||
let mark = self.performance.mark("update_import_map", None::<()>);
|
||||
|
||||
|
@ -627,23 +649,8 @@ impl Inner {
|
|||
|
||||
async fn update_registries(&mut self) -> Result<(), AnyError> {
|
||||
let mark = self.performance.mark("update_registries", None::<()>);
|
||||
self.recreate_http_client_and_dependents(self.maybe_cache_path.clone())?;
|
||||
let workspace_settings = self.config.get_workspace_settings();
|
||||
let maybe_root_path = self
|
||||
.config
|
||||
.root_uri
|
||||
.as_ref()
|
||||
.and_then(|uri| fs_util::specifier_to_file_path(uri).ok());
|
||||
self.module_registries = ModuleRegistry::new(
|
||||
&self.module_registries_location,
|
||||
ModuleRegistryOptions {
|
||||
maybe_root_path,
|
||||
maybe_ca_stores: workspace_settings.certificate_stores.clone(),
|
||||
maybe_ca_file: workspace_settings.tls_certificate.clone(),
|
||||
unsafely_ignore_certificate_errors: workspace_settings
|
||||
.unsafely_ignore_certificate_errors
|
||||
.clone(),
|
||||
},
|
||||
)?;
|
||||
for (registry, enabled) in workspace_settings.suggest.imports.hosts.iter() {
|
||||
if *enabled {
|
||||
lsp_log!("Enabling import suggestions for: {}", registry);
|
||||
|
|
|
@ -13,10 +13,10 @@ use super::path_to_regex::StringOrVec;
|
|||
use super::path_to_regex::Token;
|
||||
|
||||
use crate::deno_dir;
|
||||
use crate::file_fetcher::get_root_cert_store;
|
||||
use crate::file_fetcher::CacheSetting;
|
||||
use crate::file_fetcher::FileFetcher;
|
||||
use crate::http_cache::HttpCache;
|
||||
use crate::http_util::HttpClient;
|
||||
|
||||
use deno_core::anyhow::anyhow;
|
||||
use deno_core::error::AnyError;
|
||||
|
@ -36,7 +36,6 @@ use once_cell::sync::Lazy;
|
|||
use regex::Regex;
|
||||
use std::collections::HashMap;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use tower_lsp::lsp_types as lsp;
|
||||
|
||||
const CONFIG_PATH: &str = "/.well-known/deno-import-intellisense.json";
|
||||
|
@ -409,14 +408,6 @@ enum VariableItems {
|
|||
List(VariableItemsList),
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct ModuleRegistryOptions {
|
||||
pub maybe_root_path: Option<PathBuf>,
|
||||
pub maybe_ca_stores: Option<Vec<String>>,
|
||||
pub maybe_ca_file: Option<String>,
|
||||
pub unsafely_ignore_certificate_errors: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
/// A structure which holds the information about currently configured module
|
||||
/// registries and can provide completion information for URLs that match
|
||||
/// one of the enabled registries.
|
||||
|
@ -433,28 +424,23 @@ impl Default for ModuleRegistry {
|
|||
// custom root.
|
||||
let dir = deno_dir::DenoDir::new(None).unwrap();
|
||||
let location = dir.root.join("registries");
|
||||
Self::new(&location, ModuleRegistryOptions::default()).unwrap()
|
||||
let http_client = HttpClient::new(None, None).unwrap();
|
||||
Self::new(&location, http_client).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl ModuleRegistry {
|
||||
pub fn new(
|
||||
location: &Path,
|
||||
options: ModuleRegistryOptions,
|
||||
http_client: HttpClient,
|
||||
) -> Result<Self, AnyError> {
|
||||
let http_cache = HttpCache::new(location);
|
||||
let root_cert_store = Some(get_root_cert_store(
|
||||
options.maybe_root_path,
|
||||
options.maybe_ca_stores,
|
||||
options.maybe_ca_file,
|
||||
)?);
|
||||
let mut file_fetcher = FileFetcher::new(
|
||||
http_cache,
|
||||
CacheSetting::RespectHeaders,
|
||||
true,
|
||||
root_cert_store,
|
||||
http_client,
|
||||
BlobStore::default(),
|
||||
options.unsafely_ignore_certificate_errors,
|
||||
None,
|
||||
)?;
|
||||
file_fetcher.set_download_log_level(super::logging::lsp_log_level());
|
||||
|
@ -1262,7 +1248,8 @@ mod tests {
|
|||
let temp_dir = TempDir::new();
|
||||
let location = temp_dir.path().join("registries");
|
||||
let mut module_registry =
|
||||
ModuleRegistry::new(&location, ModuleRegistryOptions::default()).unwrap();
|
||||
ModuleRegistry::new(&location, HttpClient::new(None, None).unwrap())
|
||||
.unwrap();
|
||||
module_registry
|
||||
.enable("http://localhost:4545/")
|
||||
.await
|
||||
|
@ -1323,7 +1310,8 @@ mod tests {
|
|||
let temp_dir = TempDir::new();
|
||||
let location = temp_dir.path().join("registries");
|
||||
let mut module_registry =
|
||||
ModuleRegistry::new(&location, ModuleRegistryOptions::default()).unwrap();
|
||||
ModuleRegistry::new(&location, HttpClient::new(None, None).unwrap())
|
||||
.unwrap();
|
||||
module_registry
|
||||
.enable("http://localhost:4545/")
|
||||
.await
|
||||
|
@ -1546,7 +1534,8 @@ mod tests {
|
|||
let temp_dir = TempDir::new();
|
||||
let location = temp_dir.path().join("registries");
|
||||
let mut module_registry =
|
||||
ModuleRegistry::new(&location, ModuleRegistryOptions::default()).unwrap();
|
||||
ModuleRegistry::new(&location, HttpClient::new(None, None).unwrap())
|
||||
.unwrap();
|
||||
module_registry
|
||||
.enable_custom("http://localhost:4545/lsp/registries/deno-import-intellisense-key-first.json")
|
||||
.await
|
||||
|
@ -1616,7 +1605,8 @@ mod tests {
|
|||
let temp_dir = TempDir::new();
|
||||
let location = temp_dir.path().join("registries");
|
||||
let mut module_registry =
|
||||
ModuleRegistry::new(&location, ModuleRegistryOptions::default()).unwrap();
|
||||
ModuleRegistry::new(&location, HttpClient::new(None, None).unwrap())
|
||||
.unwrap();
|
||||
module_registry
|
||||
.enable_custom("http://localhost:4545/lsp/registries/deno-import-intellisense-complex.json")
|
||||
.await
|
||||
|
@ -1667,7 +1657,8 @@ mod tests {
|
|||
let temp_dir = TempDir::new();
|
||||
let location = temp_dir.path().join("registries");
|
||||
let module_registry =
|
||||
ModuleRegistry::new(&location, ModuleRegistryOptions::default()).unwrap();
|
||||
ModuleRegistry::new(&location, HttpClient::new(None, None).unwrap())
|
||||
.unwrap();
|
||||
let result = module_registry.check_origin("http://localhost:4545").await;
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
|
@ -1678,7 +1669,8 @@ mod tests {
|
|||
let temp_dir = TempDir::new();
|
||||
let location = temp_dir.path().join("registries");
|
||||
let module_registry =
|
||||
ModuleRegistry::new(&location, ModuleRegistryOptions::default()).unwrap();
|
||||
ModuleRegistry::new(&location, HttpClient::new(None, None).unwrap())
|
||||
.unwrap();
|
||||
let result = module_registry.check_origin("https://deno.com").await;
|
||||
assert!(result.is_err());
|
||||
let err = result.unwrap_err().to_string();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue