summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBartek IwaƄczuk <biwanczuk@gmail.com>2023-11-22 03:45:34 +0100
committerGitHub <noreply@github.com>2023-11-22 03:45:34 +0100
commita8c24d2a8b794eec343a518614cbca0a87b9e2fb (patch)
tree383562e2165e247eb15728f27412764c78c7821d
parentcc5d6df50b3e5a755bdec884ec78dc005e97b5a2 (diff)
fix: 'Promise was collected' error in REPL/jupyter (#21272)
Fixes #20528
-rw-r--r--cli/tests/integration/repl_tests.rs15
-rw-r--r--cli/tools/repl/session.rs18
-rw-r--r--cli/tools/test/mod.rs10
-rw-r--r--cli/worker.rs37
-rw-r--r--runtime/worker.rs20
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 {