summaryrefslogtreecommitdiff
path: root/cli/file_fetcher.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cli/file_fetcher.rs')
-rw-r--r--cli/file_fetcher.rs181
1 files changed, 84 insertions, 97 deletions
diff --git a/cli/file_fetcher.rs b/cli/file_fetcher.rs
index de3a76eec..ea82f151e 100644
--- a/cli/file_fetcher.rs
+++ b/cli/file_fetcher.rs
@@ -10,7 +10,6 @@ use crate::http_util::FetchOnceResult;
use crate::msg;
use deno_core::ErrBox;
use deno_core::ModuleSpecifier;
-use futures::future::Either;
use futures::future::FutureExt;
use regex::Regex;
use reqwest;
@@ -42,9 +41,6 @@ pub struct SourceFile {
pub source_code: Vec<u8>,
}
-pub type SourceFileFuture =
- dyn Future<Output = Result<SourceFile, ErrBox>> + Send;
-
/// Simple struct implementing in-process caching to prevent multiple
/// fs reads/net fetches for same file.
#[derive(Clone, Default)]
@@ -114,8 +110,10 @@ impl SourceFileFetcher {
Ok(())
}
+ // TODO(bartlomieju): fetching cached resources should be done
+ // using blocking fs syscalls
/// Required for TS compiler and source maps.
- pub fn fetch_cached_source_file(
+ pub async fn fetch_cached_source_file(
&self,
specifier: &ModuleSpecifier,
) -> Option<SourceFile> {
@@ -127,79 +125,81 @@ impl SourceFileFetcher {
// If file is not in memory cache check if it can be found
// in local cache - which effectively means trying to fetch
- // using "--cached-only" flag. We can safely block on this
- // future, because it doesn't do any asynchronous action
- // it that path.
- let fut = self.get_source_file_async(specifier.as_url(), true, false, true);
-
- futures::executor::block_on(fut).ok()
+ // using "--cached-only" flag.
+ // It should be safe to for caller block on this
+ // future, because it doesn't actually do any asynchronous
+ // action in that path.
+ self
+ .get_source_file_async(specifier.as_url(), true, false, true)
+ .await
+ .ok()
}
- pub fn fetch_source_file_async(
+ pub async fn fetch_source_file_async(
&self,
specifier: &ModuleSpecifier,
maybe_referrer: Option<ModuleSpecifier>,
- ) -> Pin<Box<SourceFileFuture>> {
+ ) -> Result<SourceFile, ErrBox> {
let module_url = specifier.as_url().to_owned();
debug!("fetch_source_file_async specifier: {} ", &module_url);
// Check if this file was already fetched and can be retrieved from in-process cache.
- if let Some(source_file) = self.source_file_cache.get(specifier.to_string())
- {
- return Box::pin(async { Ok(source_file) });
+ let maybe_cached_file = self.source_file_cache.get(specifier.to_string());
+ if let Some(source_file) = maybe_cached_file {
+ return Ok(source_file);
}
let source_file_cache = self.source_file_cache.clone();
let specifier_ = specifier.clone();
- let source_file = self.get_source_file_async(
- &module_url,
- self.use_disk_cache,
- self.no_remote,
- self.cached_only,
- );
+ let result = self
+ .get_source_file_async(
+ &module_url,
+ self.use_disk_cache,
+ self.no_remote,
+ self.cached_only,
+ )
+ .await;
- Box::pin(async move {
- match source_file.await {
- Ok(mut file) => {
- // TODO: move somewhere?
- if file.source_code.starts_with(b"#!") {
- file.source_code = filter_shebang(file.source_code);
- }
+ match result {
+ Ok(mut file) => {
+ // TODO: move somewhere?
+ if file.source_code.starts_with(b"#!") {
+ file.source_code = filter_shebang(file.source_code);
+ }
- // Cache in-process for subsequent access.
- source_file_cache.set(specifier_.to_string(), file.clone());
+ // Cache in-process for subsequent access.
+ source_file_cache.set(specifier_.to_string(), file.clone());
- Ok(file)
- }
- Err(err) => {
- let err_kind = err.kind();
- let referrer_suffix = if let Some(referrer) = maybe_referrer {
- format!(r#" from "{}""#, referrer)
- } else {
- "".to_owned()
- };
- // Hack: Check error message for "--cached-only" because the kind
- // conflicts with other errors.
- let err = if err.to_string().contains("--cached-only") {
- let msg = format!(
- r#"Cannot find module "{}"{} in cache, --cached-only is specified"#,
- module_url, referrer_suffix
- );
- DenoError::new(ErrorKind::NotFound, msg).into()
- } else if err_kind == ErrorKind::NotFound {
- let msg = format!(
- r#"Cannot resolve module "{}"{}"#,
- module_url, referrer_suffix
- );
- DenoError::new(ErrorKind::NotFound, msg).into()
- } else {
- err
- };
- Err(err)
- }
+ Ok(file)
}
- })
+ Err(err) => {
+ let err_kind = err.kind();
+ let referrer_suffix = if let Some(referrer) = maybe_referrer {
+ format!(r#" from "{}""#, referrer)
+ } else {
+ "".to_owned()
+ };
+ // Hack: Check error message for "--cached-only" because the kind
+ // conflicts with other errors.
+ let err = if err.to_string().contains("--cached-only") {
+ let msg = format!(
+ r#"Cannot find module "{}"{} in cache, --cached-only is specified"#,
+ module_url, referrer_suffix
+ );
+ DenoError::new(ErrorKind::NotFound, msg).into()
+ } else if err_kind == ErrorKind::NotFound {
+ let msg = format!(
+ r#"Cannot resolve module "{}"{}"#,
+ module_url, referrer_suffix
+ );
+ DenoError::new(ErrorKind::NotFound, msg).into()
+ } else {
+ err
+ };
+ Err(err)
+ }
+ }
}
/// This is main method that is responsible for fetching local or remote files.
@@ -213,54 +213,38 @@ impl SourceFileFetcher {
///
/// If `cached_only` is true then this method will fail for remote files
/// not already cached.
- fn get_source_file_async(
+ async fn get_source_file_async(
&self,
module_url: &Url,
use_disk_cache: bool,
no_remote: bool,
cached_only: bool,
- ) -> impl Future<Output = Result<SourceFile, ErrBox>> {
+ ) -> Result<SourceFile, ErrBox> {
let url_scheme = module_url.scheme();
let is_local_file = url_scheme == "file";
-
- if let Err(err) = SourceFileFetcher::check_if_supported_scheme(&module_url)
- {
- return Either::Left(futures::future::err(err));
- }
+ SourceFileFetcher::check_if_supported_scheme(&module_url)?;
// Local files are always fetched from disk bypassing cache entirely.
if is_local_file {
- match self.fetch_local_file(&module_url) {
- Ok(source_file) => {
- return Either::Left(futures::future::ok(source_file));
- }
- Err(err) => {
- return Either::Left(futures::future::err(err));
- }
- }
+ return self.fetch_local_file(&module_url);
}
// The file is remote, fail if `no_remote` is true.
if no_remote {
- return Either::Left(futures::future::err(
- std::io::Error::new(
- std::io::ErrorKind::NotFound,
- format!(
- "Not allowed to get remote file '{}'",
- module_url.to_string()
- ),
- )
- .into(),
- ));
+ let e = std::io::Error::new(
+ std::io::ErrorKind::NotFound,
+ format!(
+ "Not allowed to get remote file '{}'",
+ module_url.to_string()
+ ),
+ );
+ return Err(e.into());
}
// Fetch remote file and cache on-disk for subsequent access
- Either::Right(self.fetch_remote_source_async(
- &module_url,
- use_disk_cache,
- cached_only,
- 10,
- ))
+ self
+ .fetch_remote_source_async(&module_url, use_disk_cache, cached_only, 10)
+ .await
}
/// Fetch local source file.
@@ -355,16 +339,19 @@ impl SourceFileFetcher {
}
/// Asynchronously fetch remote source file specified by the URL following redirects.
+ ///
+ /// Note that this is a recursive method so it can't be "async", but rather return
+ /// Pin<Box<..>>.
fn fetch_remote_source_async(
&self,
module_url: &Url,
use_disk_cache: bool,
cached_only: bool,
redirect_limit: i64,
- ) -> Pin<Box<SourceFileFuture>> {
+ ) -> Pin<Box<dyn Future<Output = Result<SourceFile, ErrBox>>>> {
if redirect_limit < 0 {
let e = DenoError::new(ErrorKind::Http, "too many redirects".to_string());
- return futures::future::err(e.into()).boxed();
+ return futures::future::err(e.into()).boxed_local();
}
let is_blacklisted =
@@ -373,13 +360,13 @@ impl SourceFileFetcher {
if use_disk_cache && !is_blacklisted {
match self.fetch_cached_remote_source(&module_url) {
Ok(Some(source_file)) => {
- return futures::future::ok(source_file).boxed();
+ return futures::future::ok(source_file).boxed_local();
}
Ok(None) => {
// there's no cached version
}
Err(err) => {
- return futures::future::err(err).boxed();
+ return futures::future::err(err).boxed_local();
}
}
}
@@ -397,7 +384,7 @@ impl SourceFileFetcher {
)
.into(),
)
- .boxed();
+ .boxed_local();
}
eprintln!(
@@ -470,7 +457,7 @@ impl SourceFileFetcher {
}
};
- f.boxed()
+ f.boxed_local()
}
}