refactor(cli): remove Clone on ProcState (#18874)

Slowly phasing this out.
This commit is contained in:
David Sherret 2023-04-30 16:51:31 -04:00 committed by GitHub
parent 96e214d9d0
commit 9a9473533e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 84 additions and 110 deletions

View file

@ -225,7 +225,9 @@ impl TestRun {
let permissions =
Permissions::from_options(&ps.options.permissions_options())?;
test::check_specifiers(
&ps,
&ps.options,
&ps.file_fetcher,
&ps.module_load_preparer,
self
.queue
.iter()
@ -257,7 +259,7 @@ impl TestRun {
let tests: Arc<RwLock<IndexMap<usize, test::TestDescription>>> =
Arc::new(RwLock::new(IndexMap::new()));
let mut test_steps = IndexMap::new();
let worker_factory = Arc::new(ps.into_cli_main_worker_factory());
let worker_factory = Arc::new(ps.create_cli_main_worker_factory());
let join_handles = queue.into_iter().map(move |specifier| {
let specifier = specifier.clone();

View file

@ -49,17 +49,13 @@ use deno_semver::npm::NpmPackageReqReference;
use import_map::ImportMap;
use log::warn;
use std::collections::HashSet;
use std::ops::Deref;
use std::path::PathBuf;
use std::sync::Arc;
/// This structure represents state of single "deno" program.
///
/// It is shared by all created workers (thus V8 isolates).
#[derive(Clone)]
pub struct ProcState(Arc<Inner>);
pub struct Inner {
/// This structure used to represent state of single "deno" program
/// that was shared by all created workers. It morphed into being the
/// "factory" for all objects, but is being slowly phased out.
pub struct ProcState {
pub dir: DenoDir,
pub caches: Arc<Caches>,
pub file_fetcher: Arc<FileFetcher>,
@ -87,14 +83,6 @@ pub struct Inner {
pub npm_resolution: Arc<NpmResolution>,
pub package_json_deps_installer: Arc<PackageJsonDepsInstaller>,
pub cjs_resolutions: Arc<CjsResolutionStore>,
progress_bar: ProgressBar,
}
impl Deref for ProcState {
type Target = Arc<Inner>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl ProcState {
@ -123,48 +111,18 @@ impl ProcState {
/// Reset all runtime state to its default. This should be used on file
/// watcher restarts.
pub fn reset_for_file_watcher(&mut self) {
pub fn reset_for_file_watcher(&self) {
self.cjs_resolutions.clear();
self.parsed_source_cache.clear();
self.graph_container.clear();
self.0 = Arc::new(Inner {
dir: self.dir.clone(),
caches: self.caches.clone(),
options: self.options.clone(),
emit_cache: self.emit_cache.clone(),
emitter: self.emitter.clone(),
file_fetcher: self.file_fetcher.clone(),
http_client: self.http_client.clone(),
graph_container: self.graph_container.clone(),
lockfile: self.lockfile.clone(),
maybe_import_map: self.maybe_import_map.clone(),
maybe_inspector_server: self.maybe_inspector_server.clone(),
root_cert_store: self.root_cert_store.clone(),
blob_store: self.blob_store.clone(),
parsed_source_cache: self.parsed_source_cache.clone(),
resolver: self.resolver.clone(),
maybe_file_watcher_reporter: self.maybe_file_watcher_reporter.clone(),
module_graph_builder: self.module_graph_builder.clone(),
module_load_preparer: self.module_load_preparer.clone(),
node_code_translator: self.node_code_translator.clone(),
node_fs: self.node_fs.clone(),
node_resolver: self.node_resolver.clone(),
npm_api: self.npm_api.clone(),
npm_cache: self.npm_cache.clone(),
npm_resolver: self.npm_resolver.clone(),
npm_resolution: self.npm_resolution.clone(),
package_json_deps_installer: self.package_json_deps_installer.clone(),
cjs_resolutions: self.cjs_resolutions.clone(),
progress_bar: self.progress_bar.clone(),
});
self.init_watcher();
}
// Add invariant files like the import map and explicit watch flag list to
// the watcher. Dedup for build_for_file_watcher and reset_for_file_watcher.
fn init_watcher(&self) {
let files_to_watch_sender = match &self.0.maybe_file_watcher_reporter {
let files_to_watch_sender = match &self.maybe_file_watcher_reporter {
Some(reporter) => &reporter.sender,
None => return,
};
@ -338,7 +296,7 @@ impl ProcState {
type_checker,
));
Ok(ProcState(Arc::new(Inner {
Ok(ProcState {
dir,
caches,
options: cli_options,
@ -366,13 +324,12 @@ impl ProcState {
package_json_deps_installer,
cjs_resolutions: Default::default(),
module_load_preparer,
progress_bar,
})))
})
}
// todo(dsherret): this is a transitory method as we separate out
// ProcState from more code
pub fn into_cli_main_worker_factory(self) -> CliMainWorkerFactory {
pub fn create_cli_main_worker_factory(&self) -> CliMainWorkerFactory {
CliMainWorkerFactory::new(
StorageKeyResolver::from_options(&self.options),
self.npm_resolver.clone(),

View file

@ -6,6 +6,7 @@ use crate::args::TypeCheckMode;
use crate::colors;
use crate::display::write_json_to_stdout;
use crate::graph_util::graph_valid_with_cli_options;
use crate::module_loader::ModuleLoadPreparer;
use crate::ops;
use crate::proc_state::ProcState;
use crate::tools::test::format_test_error;
@ -36,7 +37,6 @@ use indexmap::IndexSet;
use log::Level;
use serde::Deserialize;
use serde::Serialize;
use std::cell::RefCell;
use std::collections::HashSet;
use std::path::Path;
use std::path::PathBuf;
@ -418,11 +418,12 @@ impl BenchReporter for ConsoleReporter {
/// Type check a collection of module and document specifiers.
async fn check_specifiers(
ps: &ProcState,
cli_options: &CliOptions,
module_load_preparer: &ModuleLoadPreparer,
specifiers: Vec<ModuleSpecifier>,
) -> Result<(), AnyError> {
let lib = ps.options.ts_type_lib_window();
ps.module_load_preparer
let lib = cli_options.ts_type_lib_window();
module_load_preparer
.prepare_module_load(
specifiers,
false,
@ -648,14 +649,15 @@ pub async fn run_benchmarks(
return Err(generic_error("No bench modules found"));
}
check_specifiers(&ps, specifiers.clone()).await?;
check_specifiers(&ps.options, &ps.module_load_preparer, specifiers.clone())
.await?;
if bench_options.no_run {
return Ok(());
}
let log_level = ps.options.log_level();
let worker_factory = Arc::new(ps.into_cli_main_worker_factory());
let worker_factory = Arc::new(ps.create_cli_main_worker_factory());
bench_specifiers(
worker_factory,
&permissions,
@ -684,14 +686,13 @@ pub async fn run_benchmarks_with_watch(
Permissions::from_options(&ps.options.permissions_options())?;
let no_check = ps.options.type_check_mode() == TypeCheckMode::None;
let ps = RefCell::new(ps);
let resolver = |changed: Option<Vec<PathBuf>>| {
let paths_to_watch = bench_options.files.include.clone();
let paths_to_watch_clone = paths_to_watch.clone();
let files_changed = changed.is_some();
let bench_options = &bench_options;
let ps = ps.borrow().clone();
let module_graph_builder = ps.module_graph_builder.clone();
let cli_options = ps.options.clone();
async move {
let bench_modules =
@ -703,11 +704,10 @@ pub async fn run_benchmarks_with_watch(
} else {
bench_modules.clone()
};
let graph = ps
.module_graph_builder
let graph = module_graph_builder
.create_graph(bench_modules.clone())
.await?;
graph_valid_with_cli_options(&graph, &bench_modules, &ps.options)?;
graph_valid_with_cli_options(&graph, &bench_modules, &cli_options)?;
// TODO(@kitsonk) - This should be totally derivable from the graph.
for specifier in bench_modules {
@ -800,8 +800,10 @@ pub async fn run_benchmarks_with_watch(
let operation = |modules_to_reload: Vec<ModuleSpecifier>| {
let permissions = &permissions;
let bench_options = &bench_options;
ps.borrow_mut().reset_for_file_watcher();
let ps = ps.borrow().clone();
ps.reset_for_file_watcher();
let module_load_preparer = ps.module_load_preparer.clone();
let cli_options = ps.options.clone();
let worker_factory = Arc::new(ps.create_cli_main_worker_factory());
async move {
let specifiers =
@ -810,14 +812,14 @@ pub async fn run_benchmarks_with_watch(
.filter(|specifier| modules_to_reload.contains(specifier))
.collect::<Vec<ModuleSpecifier>>();
check_specifiers(&ps, specifiers.clone()).await?;
check_specifiers(&cli_options, &module_load_preparer, specifiers.clone())
.await?;
if bench_options.no_run {
return Ok(());
}
let log_level = ps.options.log_level();
let worker_factory = Arc::new(ps.into_cli_main_worker_factory());
let log_level = cli_options.log_level();
bench_specifiers(
worker_factory,
permissions,
@ -834,7 +836,7 @@ pub async fn run_benchmarks_with_watch(
}
};
let clear_screen = !ps.borrow().options.no_clear_screen();
let clear_screen = !ps.options.no_clear_screen();
file_watcher::watch_func(
resolver,
operation,

View file

@ -108,7 +108,7 @@ pub async fn run(flags: Flags, repl_flags: ReplFlags) -> Result<i32, AnyError> {
let resolver = ps.resolver.clone();
let dir = ps.dir.clone();
let file_fetcher = ps.file_fetcher.clone();
let worker_factory = ps.into_cli_main_worker_factory();
let worker_factory = ps.create_cli_main_worker_factory();
let mut worker = worker_factory
.create_main_worker(main_module, permissions)

View file

@ -47,7 +47,7 @@ To grant permissions, set them before the script argument. For example:
let permissions = PermissionsContainer::new(Permissions::from_options(
&ps.options.permissions_options(),
)?);
let worker_factory = ps.into_cli_main_worker_factory();
let worker_factory = ps.create_cli_main_worker_factory();
let mut worker = worker_factory
.create_main_worker(main_module, permissions)
.await?;
@ -78,7 +78,7 @@ pub async fn run_from_stdin(flags: Flags) -> Result<i32, AnyError> {
// to allow module access by TS compiler
ps.file_fetcher.insert_cached(source_file);
let worker_factory = ps.into_cli_main_worker_factory();
let worker_factory = ps.create_cli_main_worker_factory();
let mut worker = worker_factory
.create_main_worker(main_module, permissions)
.await?;
@ -90,19 +90,19 @@ pub async fn run_from_stdin(flags: Flags) -> Result<i32, AnyError> {
// code properly.
async fn run_with_watch(flags: Flags) -> Result<i32, AnyError> {
let (sender, receiver) = tokio::sync::mpsc::unbounded_channel();
let mut ps =
let ps =
ProcState::from_flags_for_file_watcher(flags, sender.clone()).await?;
let clear_screen = !ps.options.no_clear_screen();
let main_module = ps.options.resolve_main_module()?;
let operation = |main_module: ModuleSpecifier| {
ps.reset_for_file_watcher();
let ps = ps.clone();
let permissions = PermissionsContainer::new(Permissions::from_options(
&ps.options.permissions_options(),
)?);
let worker_factory = ps.create_cli_main_worker_factory();
Ok(async move {
let permissions = PermissionsContainer::new(Permissions::from_options(
&ps.options.permissions_options(),
)?);
let worker_factory = ps.into_cli_main_worker_factory();
let worker = worker_factory
.create_main_worker(main_module, permissions)
.await?;
@ -157,7 +157,7 @@ pub async fn eval_command(
ps.file_fetcher.insert_cached(file);
let mut worker = ps
.into_cli_main_worker_factory()
.create_cli_main_worker_factory()
.create_main_worker(main_module, permissions)
.await?;
let exit_code = worker.run().await?;

View file

@ -7,7 +7,9 @@ use crate::args::TypeCheckMode;
use crate::colors;
use crate::display;
use crate::file_fetcher::File;
use crate::file_fetcher::FileFetcher;
use crate::graph_util::graph_valid_with_cli_options;
use crate::module_loader::ModuleLoadPreparer;
use crate::ops;
use crate::proc_state::ProcState;
use crate::util::checksum;
@ -49,7 +51,6 @@ use rand::seq::SliceRandom;
use rand::SeedableRng;
use regex::Regex;
use serde::Deserialize;
use std::cell::RefCell;
use std::collections::BTreeMap;
use std::collections::BTreeSet;
use std::collections::HashMap;
@ -1200,13 +1201,13 @@ fn extract_files_from_fenced_blocks(
}
async fn fetch_inline_files(
ps: &ProcState,
file_fetcher: &FileFetcher,
specifiers: Vec<ModuleSpecifier>,
) -> Result<Vec<File>, AnyError> {
let mut files = Vec::new();
for specifier in specifiers {
let fetch_permissions = PermissionsContainer::allow_all();
let file = ps.file_fetcher.fetch(&specifier, fetch_permissions).await?;
let file = file_fetcher.fetch(&specifier, fetch_permissions).await?;
let inline_files = if file.media_type == MediaType::Unknown {
extract_files_from_fenced_blocks(
@ -1230,12 +1231,14 @@ async fn fetch_inline_files(
/// Type check a collection of module and document specifiers.
pub async fn check_specifiers(
ps: &ProcState,
cli_options: &CliOptions,
file_fetcher: &FileFetcher,
module_load_preparer: &ModuleLoadPreparer,
specifiers: Vec<(ModuleSpecifier, TestMode)>,
) -> Result<(), AnyError> {
let lib = ps.options.ts_type_lib_window();
let lib = cli_options.ts_type_lib_window();
let inline_files = fetch_inline_files(
ps,
file_fetcher,
specifiers
.iter()
.filter_map(|(specifier, mode)| {
@ -1256,10 +1259,10 @@ pub async fn check_specifiers(
.collect();
for file in inline_files {
ps.file_fetcher.insert_cached(file);
file_fetcher.insert_cached(file);
}
ps.module_load_preparer
module_load_preparer
.prepare_module_load(
specifiers,
false,
@ -1280,7 +1283,7 @@ pub async fn check_specifiers(
})
.collect();
ps.module_load_preparer
module_load_preparer
.prepare_module_load(
module_specifiers,
false,
@ -1601,15 +1604,14 @@ fn collect_specifiers_with_test_mode(
/// cannot be run, and therefore need to be marked as `TestMode::Documentation`
/// as well.
async fn fetch_specifiers_with_test_mode(
ps: &ProcState,
file_fetcher: &FileFetcher,
files: &FilesConfig,
doc: &bool,
) -> Result<Vec<(ModuleSpecifier, TestMode)>, AnyError> {
let mut specifiers_with_mode = collect_specifiers_with_test_mode(files, doc)?;
for (specifier, mode) in &mut specifiers_with_mode {
let file = ps
.file_fetcher
let file = file_fetcher
.fetch(specifier, PermissionsContainer::allow_all())
.await?;
@ -1636,7 +1638,7 @@ pub async fn run_tests(
let log_level = ps.options.log_level();
let specifiers_with_mode = fetch_specifiers_with_test_mode(
&ps,
&ps.file_fetcher,
&test_options.files,
&test_options.doc,
)
@ -1646,13 +1648,19 @@ pub async fn run_tests(
return Err(generic_error("No test modules found"));
}
check_specifiers(&ps, specifiers_with_mode.clone()).await?;
check_specifiers(
&ps.options,
&ps.file_fetcher,
&ps.module_load_preparer,
specifiers_with_mode.clone(),
)
.await?;
if test_options.no_run {
return Ok(());
}
let worker_factory = Arc::new(ps.into_cli_main_worker_factory());
let worker_factory = Arc::new(ps.create_cli_main_worker_factory());
test_specifiers(
worker_factory,
@ -1693,14 +1701,13 @@ pub async fn run_tests_with_watch(
let no_check = ps.options.type_check_mode() == TypeCheckMode::None;
let log_level = ps.options.log_level();
let ps = RefCell::new(ps);
let resolver = |changed: Option<Vec<PathBuf>>| {
let paths_to_watch = test_options.files.include.clone();
let paths_to_watch_clone = paths_to_watch.clone();
let files_changed = changed.is_some();
let test_options = &test_options;
let ps = ps.borrow().clone();
let cli_options = ps.options.clone();
let module_graph_builder = ps.module_graph_builder.clone();
async move {
let test_modules = if test_options.doc {
@ -1715,11 +1722,10 @@ pub async fn run_tests_with_watch(
} else {
test_modules.clone()
};
let graph = ps
.module_graph_builder
let graph = module_graph_builder
.create_graph(test_modules.clone())
.await?;
graph_valid_with_cli_options(&graph, &test_modules, &ps.options)?;
graph_valid_with_cli_options(&graph, &test_modules, &cli_options)?;
// TODO(@kitsonk) - This should be totally derivable from the graph.
for specifier in test_modules {
@ -1812,12 +1818,15 @@ pub async fn run_tests_with_watch(
let operation = |modules_to_reload: Vec<ModuleSpecifier>| {
let permissions = &permissions;
let test_options = &test_options;
ps.borrow_mut().reset_for_file_watcher();
let ps = ps.borrow().clone();
ps.reset_for_file_watcher();
let cli_options = ps.options.clone();
let file_fetcher = ps.file_fetcher.clone();
let module_load_preparer = ps.module_load_preparer.clone();
let worker_factory = Arc::new(ps.create_cli_main_worker_factory());
async move {
let specifiers_with_mode = fetch_specifiers_with_test_mode(
&ps,
&file_fetcher,
&test_options.files,
&test_options.doc,
)
@ -1826,14 +1835,18 @@ pub async fn run_tests_with_watch(
.filter(|(specifier, _)| modules_to_reload.contains(specifier))
.collect::<Vec<(ModuleSpecifier, TestMode)>>();
check_specifiers(&ps, specifiers_with_mode.clone()).await?;
check_specifiers(
&cli_options,
&file_fetcher,
&module_load_preparer,
specifiers_with_mode.clone(),
)
.await?;
if test_options.no_run {
return Ok(());
}
let worker_factory = Arc::new(ps.into_cli_main_worker_factory());
test_specifiers(
worker_factory,
permissions,
@ -1874,7 +1887,7 @@ pub async fn run_tests_with_watch(
}
});
let clear_screen = !ps.borrow().options.no_clear_screen();
let clear_screen = !ps.options.no_clear_screen();
file_watcher::watch_func(
resolver,
operation,