Created
July 20, 2019 18:45
-
-
Save bartlomieju/ffb21f610e23d2e03db437671b561ec2 to your computer and use it in GitHub Desktop.
Futures recursion
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// Asynchronously fetch remote source file specified by the URL following redirects. | |
fn fetch_remote_source_async( | |
self: &Self, | |
module_url: &Url, | |
) -> Box<impl Future<Item = SourceFile, Error = ErrBox>> { | |
use crate::http_util::FetchOnceResult; | |
let download_job = self.progress.add("Download", &module_url.to_string()); | |
let module_uri = url_into_uri(&module_url); | |
let dir = self.clone(); | |
let module_url = module_url.clone(); | |
// Single pass fetch, either yields code or yields redirect. | |
let f = http_util::fetch_string_once(module_uri).and_then( | |
move |fetch_once_result| { | |
match fetch_once_result { | |
FetchOnceResult::Redirect(uri) => { | |
// If redirects, update module_name and filename for next looped call. | |
let new_module_url = Url::parse(&uri.to_string()).expect("http::uri::Uri should be parseable as Url"); | |
dir.save_source_code_headers( | |
&module_url, | |
None, | |
Some(new_module_url.to_string()) | |
).unwrap(); | |
// Explicit drop to keep reference alive until future completes. | |
drop(download_job); | |
let module_url = module_url.clone(); | |
// Recurse | |
let fut = dir.get_source_file_async(&new_module_url, dir.use_disk_cache, dir.no_remote_fetch) | |
.and_then(move |source_file| { | |
let mut source_file = source_file; | |
source_file.redirect_source_url = Some(module_url); | |
futures::future::ok(source_file) | |
}); | |
Either::A(fut) | |
} | |
FetchOnceResult::Code(source, maybe_content_type) => { | |
// TODO: move caching logic outside this function | |
// We land on the code. | |
dir.save_source_code_headers( | |
&module_url, | |
maybe_content_type.clone(), | |
None, | |
).unwrap(); | |
dir.save_source_code( | |
&module_url, | |
&source | |
).unwrap(); | |
let filepath = dir | |
.deps_cache | |
.location | |
.join(dir.deps_cache.get_cache_filename(&module_url)); | |
let media_type = map_content_type( | |
&filepath, | |
maybe_content_type.as_ref().map(String::as_str), | |
); | |
let source_file = SourceFile { | |
url: module_url.clone(), | |
redirect_source_url: None, | |
filename: filepath, | |
media_type, | |
source_code: source.as_bytes().to_owned(), | |
}; | |
// Explicit drop to keep reference alive until future completes. | |
drop(download_job); | |
Either::B(futures::future::ok(source_file)) | |
} | |
} | |
}, | |
); | |
Box::new(f) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment