mirror of
https://github.com/denoland/deno.git
synced 2024-11-24 15:19:26 -05:00
perf: skip saving to emit cache after first failure (#24896)
This commit is contained in:
parent
93d479252b
commit
6fce23c54e
6 changed files with 41 additions and 16 deletions
22
cli/cache/emit.rs
vendored
22
cli/cache/emit.rs
vendored
|
@ -6,6 +6,7 @@ use deno_ast::ModuleSpecifier;
|
||||||
use deno_core::anyhow::anyhow;
|
use deno_core::anyhow::anyhow;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_core::serde_json;
|
use deno_core::serde_json;
|
||||||
|
use deno_core::unsync::sync::AtomicFlag;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
|
@ -19,10 +20,10 @@ struct EmitMetadata {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The cache that stores previously emitted files.
|
/// The cache that stores previously emitted files.
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct EmitCache {
|
pub struct EmitCache {
|
||||||
disk_cache: DiskCache,
|
disk_cache: DiskCache,
|
||||||
cli_version: &'static str,
|
cli_version: &'static str,
|
||||||
|
emit_failed_flag: AtomicFlag,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EmitCache {
|
impl EmitCache {
|
||||||
|
@ -30,6 +31,7 @@ impl EmitCache {
|
||||||
Self {
|
Self {
|
||||||
disk_cache,
|
disk_cache,
|
||||||
cli_version: crate::version::deno(),
|
cli_version: crate::version::deno(),
|
||||||
|
emit_failed_flag: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,12 +89,10 @@ impl EmitCache {
|
||||||
code: &[u8],
|
code: &[u8],
|
||||||
) {
|
) {
|
||||||
if let Err(err) = self.set_emit_code_result(specifier, source_hash, code) {
|
if let Err(err) = self.set_emit_code_result(specifier, source_hash, code) {
|
||||||
// should never error here, but if it ever does don't fail
|
// might error in cases such as a readonly file system
|
||||||
if cfg!(debug_assertions) {
|
log::debug!("Error saving emit data ({}): {}", specifier, err);
|
||||||
panic!("Error saving emit data ({specifier}): {err}");
|
// assume the cache can't be written to and disable caching to it
|
||||||
} else {
|
self.emit_failed_flag.raise();
|
||||||
log::debug!("Error saving emit data({}): {}", specifier, err);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,6 +102,11 @@ impl EmitCache {
|
||||||
source_hash: u64,
|
source_hash: u64,
|
||||||
code: &[u8],
|
code: &[u8],
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), AnyError> {
|
||||||
|
if self.emit_failed_flag.is_raised() {
|
||||||
|
log::debug!("Skipped emit cache save of {}", specifier);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
let meta_filename = self
|
let meta_filename = self
|
||||||
.get_meta_filename(specifier)
|
.get_meta_filename(specifier)
|
||||||
.ok_or_else(|| anyhow!("Could not get meta filename."))?;
|
.ok_or_else(|| anyhow!("Could not get meta filename."))?;
|
||||||
|
@ -161,6 +166,7 @@ mod test {
|
||||||
let cache = EmitCache {
|
let cache = EmitCache {
|
||||||
disk_cache: disk_cache.clone(),
|
disk_cache: disk_cache.clone(),
|
||||||
cli_version: "1.0.0",
|
cli_version: "1.0.0",
|
||||||
|
emit_failed_flag: Default::default(),
|
||||||
};
|
};
|
||||||
let to_string =
|
let to_string =
|
||||||
|bytes: Vec<u8>| -> String { String::from_utf8(bytes).unwrap() };
|
|bytes: Vec<u8>| -> String { String::from_utf8(bytes).unwrap() };
|
||||||
|
@ -192,6 +198,7 @@ mod test {
|
||||||
let cache = EmitCache {
|
let cache = EmitCache {
|
||||||
disk_cache: disk_cache.clone(),
|
disk_cache: disk_cache.clone(),
|
||||||
cli_version: "2.0.0",
|
cli_version: "2.0.0",
|
||||||
|
emit_failed_flag: Default::default(),
|
||||||
};
|
};
|
||||||
assert_eq!(cache.get_emit_code(&specifier1, 10), None);
|
assert_eq!(cache.get_emit_code(&specifier1, 10), None);
|
||||||
cache.set_emit_code(&specifier1, 5, emit_code1.as_bytes());
|
cache.set_emit_code(&specifier1, 5, emit_code1.as_bytes());
|
||||||
|
@ -200,6 +207,7 @@ mod test {
|
||||||
let cache = EmitCache {
|
let cache = EmitCache {
|
||||||
disk_cache,
|
disk_cache,
|
||||||
cli_version: "2.0.0",
|
cli_version: "2.0.0",
|
||||||
|
emit_failed_flag: Default::default(),
|
||||||
};
|
};
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
cache.get_emit_code(&specifier1, 5).map(to_string),
|
cache.get_emit_code(&specifier1, 5).map(to_string),
|
||||||
|
|
4
cli/cache/mod.rs
vendored
4
cli/cache/mod.rs
vendored
|
@ -106,7 +106,7 @@ pub use deno_cache_dir::HttpCache;
|
||||||
/// A "wrapper" for the FileFetcher and DiskCache for the Deno CLI that provides
|
/// A "wrapper" for the FileFetcher and DiskCache for the Deno CLI that provides
|
||||||
/// a concise interface to the DENO_DIR when building module graphs.
|
/// a concise interface to the DENO_DIR when building module graphs.
|
||||||
pub struct FetchCacher {
|
pub struct FetchCacher {
|
||||||
emit_cache: EmitCache,
|
emit_cache: Arc<EmitCache>,
|
||||||
file_fetcher: Arc<FileFetcher>,
|
file_fetcher: Arc<FileFetcher>,
|
||||||
file_header_overrides: HashMap<ModuleSpecifier, HashMap<String, String>>,
|
file_header_overrides: HashMap<ModuleSpecifier, HashMap<String, String>>,
|
||||||
global_http_cache: Arc<GlobalHttpCache>,
|
global_http_cache: Arc<GlobalHttpCache>,
|
||||||
|
@ -118,7 +118,7 @@ pub struct FetchCacher {
|
||||||
|
|
||||||
impl FetchCacher {
|
impl FetchCacher {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
emit_cache: EmitCache,
|
emit_cache: Arc<EmitCache>,
|
||||||
file_fetcher: Arc<FileFetcher>,
|
file_fetcher: Arc<FileFetcher>,
|
||||||
file_header_overrides: HashMap<ModuleSpecifier, HashMap<String, String>>,
|
file_header_overrides: HashMap<ModuleSpecifier, HashMap<String, String>>,
|
||||||
global_http_cache: Arc<GlobalHttpCache>,
|
global_http_cache: Arc<GlobalHttpCache>,
|
||||||
|
|
|
@ -18,7 +18,7 @@ use deno_graph::ModuleGraph;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub struct Emitter {
|
pub struct Emitter {
|
||||||
emit_cache: EmitCache,
|
emit_cache: Arc<EmitCache>,
|
||||||
parsed_source_cache: Arc<ParsedSourceCache>,
|
parsed_source_cache: Arc<ParsedSourceCache>,
|
||||||
transpile_and_emit_options:
|
transpile_and_emit_options:
|
||||||
Arc<(deno_ast::TranspileOptions, deno_ast::EmitOptions)>,
|
Arc<(deno_ast::TranspileOptions, deno_ast::EmitOptions)>,
|
||||||
|
@ -28,7 +28,7 @@ pub struct Emitter {
|
||||||
|
|
||||||
impl Emitter {
|
impl Emitter {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
emit_cache: EmitCache,
|
emit_cache: Arc<EmitCache>,
|
||||||
parsed_source_cache: Arc<ParsedSourceCache>,
|
parsed_source_cache: Arc<ParsedSourceCache>,
|
||||||
transpile_options: deno_ast::TranspileOptions,
|
transpile_options: deno_ast::TranspileOptions,
|
||||||
emit_options: deno_ast::EmitOptions,
|
emit_options: deno_ast::EmitOptions,
|
||||||
|
|
|
@ -164,7 +164,7 @@ struct CliFactoryServices {
|
||||||
global_http_cache: Deferred<Arc<GlobalHttpCache>>,
|
global_http_cache: Deferred<Arc<GlobalHttpCache>>,
|
||||||
http_cache: Deferred<Arc<dyn HttpCache>>,
|
http_cache: Deferred<Arc<dyn HttpCache>>,
|
||||||
http_client_provider: Deferred<Arc<HttpClientProvider>>,
|
http_client_provider: Deferred<Arc<HttpClientProvider>>,
|
||||||
emit_cache: Deferred<EmitCache>,
|
emit_cache: Deferred<Arc<EmitCache>>,
|
||||||
emitter: Deferred<Arc<Emitter>>,
|
emitter: Deferred<Arc<Emitter>>,
|
||||||
fs: Deferred<Arc<dyn deno_fs::FileSystem>>,
|
fs: Deferred<Arc<dyn deno_fs::FileSystem>>,
|
||||||
main_graph_container: Deferred<Arc<MainModuleGraphContainer>>,
|
main_graph_container: Deferred<Arc<MainModuleGraphContainer>>,
|
||||||
|
@ -492,9 +492,9 @@ impl CliFactory {
|
||||||
.get_or_init(|| maybe_file_watcher_reporter)
|
.get_or_init(|| maybe_file_watcher_reporter)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn emit_cache(&self) -> Result<&EmitCache, AnyError> {
|
pub fn emit_cache(&self) -> Result<&Arc<EmitCache>, AnyError> {
|
||||||
self.services.emit_cache.get_or_try_init(|| {
|
self.services.emit_cache.get_or_try_init(|| {
|
||||||
Ok(EmitCache::new(self.deno_dir()?.gen_cache.clone()))
|
Ok(Arc::new(EmitCache::new(self.deno_dir()?.gen_cache.clone())))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -364,7 +364,7 @@ pub struct ModuleGraphBuilder {
|
||||||
parsed_source_cache: Arc<ParsedSourceCache>,
|
parsed_source_cache: Arc<ParsedSourceCache>,
|
||||||
lockfile: Option<Arc<CliLockfile>>,
|
lockfile: Option<Arc<CliLockfile>>,
|
||||||
maybe_file_watcher_reporter: Option<FileWatcherReporter>,
|
maybe_file_watcher_reporter: Option<FileWatcherReporter>,
|
||||||
emit_cache: cache::EmitCache,
|
emit_cache: Arc<cache::EmitCache>,
|
||||||
file_fetcher: Arc<FileFetcher>,
|
file_fetcher: Arc<FileFetcher>,
|
||||||
global_http_cache: Arc<GlobalHttpCache>,
|
global_http_cache: Arc<GlobalHttpCache>,
|
||||||
}
|
}
|
||||||
|
@ -381,7 +381,7 @@ impl ModuleGraphBuilder {
|
||||||
parsed_source_cache: Arc<ParsedSourceCache>,
|
parsed_source_cache: Arc<ParsedSourceCache>,
|
||||||
lockfile: Option<Arc<CliLockfile>>,
|
lockfile: Option<Arc<CliLockfile>>,
|
||||||
maybe_file_watcher_reporter: Option<FileWatcherReporter>,
|
maybe_file_watcher_reporter: Option<FileWatcherReporter>,
|
||||||
emit_cache: cache::EmitCache,
|
emit_cache: Arc<cache::EmitCache>,
|
||||||
file_fetcher: Arc<FileFetcher>,
|
file_fetcher: Arc<FileFetcher>,
|
||||||
global_http_cache: Arc<GlobalHttpCache>,
|
global_http_cache: Arc<GlobalHttpCache>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
|
|
@ -5342,3 +5342,20 @@ async fn listen_tls_alpn_fail() {
|
||||||
let status = child.wait().unwrap();
|
let status = child.wait().unwrap();
|
||||||
assert!(status.success());
|
assert!(status.success());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Couldn't get the directory readonly on windows on the CI
|
||||||
|
// so gave up because this being tested on unix is good enough
|
||||||
|
#[cfg(unix)]
|
||||||
|
#[test]
|
||||||
|
fn emit_failed_readonly_file_system() {
|
||||||
|
let context = TestContextBuilder::default().use_temp_cwd().build();
|
||||||
|
context.deno_dir().path().canonicalize().make_dir_readonly();
|
||||||
|
let temp_dir = context.temp_dir().path().canonicalize();
|
||||||
|
temp_dir.join("main.ts").write("import './other.ts';");
|
||||||
|
temp_dir.join("other.ts").write("console.log('hi');");
|
||||||
|
let output = context
|
||||||
|
.new_command()
|
||||||
|
.args("run --log-level=debug main.ts")
|
||||||
|
.run();
|
||||||
|
output.assert_matches_text("[WILDCARD]Error saving emit data ([WILDLINE]main.ts)[WILDCARD]Skipped emit cache save of [WILDLINE]other.ts[WILDCARD]hi[WILDCARD]");
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue