diff options
author | Bartek IwaĆczuk <biwanczuk@gmail.com> | 2023-11-22 03:45:34 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-22 03:45:34 +0100 |
commit | a8c24d2a8b794eec343a518614cbca0a87b9e2fb (patch) | |
tree | 383562e2165e247eb15728f27412764c78c7821d | |
parent | cc5d6df50b3e5a755bdec884ec78dc005e97b5a2 (diff) |
fix: 'Promise was collected' error in REPL/jupyter (#21272)
Fixes #20528
-rw-r--r-- | cli/tests/integration/repl_tests.rs | 15 | ||||
-rw-r--r-- | cli/tools/repl/session.rs | 18 | ||||
-rw-r--r-- | cli/tools/test/mod.rs | 10 | ||||
-rw-r--r-- | cli/worker.rs | 37 | ||||
-rw-r--r-- | runtime/worker.rs | 20 |
5 files changed, 74 insertions, 26 deletions
diff --git a/cli/tests/integration/repl_tests.rs b/cli/tests/integration/repl_tests.rs index a4675c388..6c208ac2c 100644 --- a/cli/tests/integration/repl_tests.rs +++ b/cli/tests/integration/repl_tests.rs @@ -1093,3 +1093,18 @@ fn env_file() { assert_contains!(console.all_output(), "BAR",); }); } + +// Regression test for https://github.com/denoland/deno/issues/20528 +#[test] +fn pty_promise_was_collected_regression_test() { + let (out, err) = util::run_and_collect_output_with_args( + true, + vec!["repl"], + Some(vec!["new Uint8Array(64 * 1024 * 1024)"]), + None, + false, + ); + + assert_contains!(out, "Uint8Array(67108864)"); + assert!(err.is_empty()); +} diff --git a/cli/tools/repl/session.rs b/cli/tools/repl/session.rs index b46f73d5a..0a0dd6648 100644 --- a/cli/tools/repl/session.rs +++ b/cli/tools/repl/session.rs @@ -38,6 +38,7 @@ use deno_core::serde_json; use deno_core::serde_json::Value; use deno_core::unsync::spawn; use deno_core::LocalInspectorSession; +use deno_core::PollEventLoopOptions; use deno_graph::source::ResolutionMode; use deno_graph::source::Resolver; use deno_graph::Position; @@ -200,10 +201,15 @@ impl ReplSession { let mut session = worker.create_inspector_session().await; worker + .js_runtime .with_event_loop( session .post_message::<()>("Runtime.enable", None) .boxed_local(), + PollEventLoopOptions { + wait_for_inspector: false, + ..Default::default() + }, ) .await?; @@ -291,7 +297,17 @@ impl ReplSession { ) -> Result<Value, AnyError> { self .worker - .with_event_loop(self.session.post_message(method, params).boxed_local()) + .js_runtime + .with_event_loop( + self.session.post_message(method, params).boxed_local(), + PollEventLoopOptions { + wait_for_inspector: false, + // NOTE(bartlomieju): this is an important bit; we don't want to pump V8 + // message loop here, so that GC won't run. Otherwise, the resulting + // object might be GC'ed before we have a chance to inspect it. + pump_v8_message_loop: false, + }, + ) .await } diff --git a/cli/tools/test/mod.rs b/cli/tools/test/mod.rs index 5e34e345f..836004f86 100644 --- a/cli/tools/test/mod.rs +++ b/cli/tools/test/mod.rs @@ -44,6 +44,7 @@ use deno_core::unsync::spawn_blocking; use deno_core::url::Url; use deno_core::v8; use deno_core::ModuleSpecifier; +use deno_core::PollEventLoopOptions; use deno_runtime::deno_io::Stdio; use deno_runtime::deno_io::StdioPipe; use deno_runtime::fmt_errors::format_js_error; @@ -467,7 +468,14 @@ pub async fn test_specifier( if let Some(coverage_collector) = coverage_collector.as_mut() { worker - .with_event_loop(coverage_collector.stop_collecting().boxed_local()) + .js_runtime + .with_event_loop( + coverage_collector.stop_collecting().boxed_local(), + PollEventLoopOptions { + wait_for_inspector: false, + ..Default::default() + }, + ) .await?; } Ok(()) diff --git a/cli/worker.rs b/cli/worker.rs index 8834f59ce..8ce46c077 100644 --- a/cli/worker.rs +++ b/cli/worker.rs @@ -19,6 +19,7 @@ use deno_core::Extension; use deno_core::FeatureChecker; use deno_core::ModuleId; use deno_core::ModuleLoader; +use deno_core::PollEventLoopOptions; use deno_core::SharedArrayBufferStore; use deno_core::SourceMapGetter; use deno_lockfile::Lockfile; @@ -209,13 +210,27 @@ impl CliMainWorker { if let Some(coverage_collector) = maybe_coverage_collector.as_mut() { self .worker - .with_event_loop(coverage_collector.stop_collecting().boxed_local()) + .js_runtime + .with_event_loop( + coverage_collector.stop_collecting().boxed_local(), + PollEventLoopOptions { + wait_for_inspector: false, + ..Default::default() + }, + ) .await?; } if let Some(hmr_runner) = maybe_hmr_runner.as_mut() { self .worker - .with_event_loop(hmr_runner.stop().boxed_local()) + .js_runtime + .with_event_loop( + hmr_runner.stop().boxed_local(), + PollEventLoopOptions { + wait_for_inspector: false, + ..Default::default() + }, + ) .await?; } @@ -324,7 +339,14 @@ impl CliMainWorker { tools::coverage::CoverageCollector::new(coverage_dir, session); self .worker - .with_event_loop(coverage_collector.start_collecting().boxed_local()) + .js_runtime + .with_event_loop( + coverage_collector.start_collecting().boxed_local(), + PollEventLoopOptions { + wait_for_inspector: false, + ..Default::default() + }, + ) .await?; Ok(Some(coverage_collector)) } else { @@ -348,7 +370,14 @@ impl CliMainWorker { self .worker - .with_event_loop(hmr_runner.start().boxed_local()) + .js_runtime + .with_event_loop( + hmr_runner.start().boxed_local(), + PollEventLoopOptions { + wait_for_inspector: false, + ..Default::default() + }, + ) .await?; Ok(Some(hmr_runner)) diff --git a/runtime/worker.rs b/runtime/worker.rs index e83c8a720..c60e189f7 100644 --- a/runtime/worker.rs +++ b/runtime/worker.rs @@ -1,6 +1,5 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -use std::pin::Pin; use std::rc::Rc; use std::sync::atomic::AtomicI32; use std::sync::atomic::Ordering::Relaxed; @@ -15,7 +14,6 @@ use deno_cache::SqliteBackedCache; use deno_core::ascii_str; use deno_core::error::AnyError; use deno_core::error::JsError; -use deno_core::futures::Future; use deno_core::merge_op_metrics; use deno_core::v8; use deno_core::CompiledWasmModuleStore; @@ -615,24 +613,6 @@ impl MainWorker { self.js_runtime.run_event_loop(wait_for_inspector).await } - /// A utility function that runs provided future concurrently with the event loop. - /// - /// Useful when using a local inspector session. - pub async fn with_event_loop<'a, T>( - &mut self, - mut fut: Pin<Box<dyn Future<Output = T> + 'a>>, - ) -> T { - loop { - tokio::select! { - biased; - result = &mut fut => { - return result; - } - _ = self.run_event_loop(false) => {} - }; - } - } - /// Return exit code set by the executed code (either in main worker /// or one of child web workers). pub fn exit_code(&self) -> i32 { |