summaryrefslogtreecommitdiff
path: root/cli/tools/test.rs
diff options
context:
space:
mode:
authorBartek IwaƄczuk <biwanczuk@gmail.com>2023-06-07 23:50:14 +0200
committerGitHub <noreply@github.com>2023-06-07 23:50:14 +0200
commit19f82b0eaa14f0df58fdfc685e60c8560582c5a4 (patch)
tree0269a3fb0e70fb37856b5d4a2b5a1e737be9feb7 /cli/tools/test.rs
parent7e91f74d2b00cdc64042ba66e45d912fa2d9b647 (diff)
refactor(core): use JoinSet instead of FuturesUnordered (#19378)
This commit migrates "deno_core" from using "FuturesUnordered" to "tokio::task::JoinSet". This makes every op to be a separate Tokio task and should unlock better utilization of kqueue/epoll. There were two quirks added to this PR: - because of the fact that "JoinSet" immediately polls spawn tasks, op sanitizers can give false positives in some cases, this was alleviated by polling event loop once before running a test with "deno test", which gives canceled ops an opportunity to settle - "JsRuntimeState::waker" was moved to "OpState::waker" so that FFI API can still use threadsafe functions - without this change the registered wakers were wrong as they would not wake up the whole "JsRuntime" but the task associated with an op --------- Co-authored-by: Matt Mastracci <matthew@mastracci.com>
Diffstat (limited to 'cli/tools/test.rs')
-rw-r--r--cli/tools/test.rs17
1 files changed, 17 insertions, 0 deletions
diff --git a/cli/tools/test.rs b/cli/tools/test.rs
index ebe4deb9a..6f32d69e4 100644
--- a/cli/tools/test.rs
+++ b/cli/tools/test.rs
@@ -28,6 +28,7 @@ use deno_core::error::AnyError;
use deno_core::error::JsError;
use deno_core::futures::future;
use deno_core::futures::stream;
+use deno_core::futures::task::noop_waker;
use deno_core::futures::FutureExt;
use deno_core::futures::StreamExt;
use deno_core::located_script_name;
@@ -66,6 +67,7 @@ use std::sync::atomic::AtomicBool;
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering;
use std::sync::Arc;
+use std::task::Context;
use std::time::Duration;
use std::time::Instant;
use std::time::SystemTime;
@@ -1006,6 +1008,21 @@ pub async fn test_specifier(
continue;
}
sender.send(TestEvent::Wait(desc.id))?;
+
+ // TODO(bartlomieju): this is a nasty (beautiful) hack, that was required
+ // when switching `JsRuntime` from `FuturesUnordered` to `JoinSet`. With
+ // `JoinSet` all pending ops are immediately polled and that caused a problem
+ // when some async ops were fired and canceled before running tests (giving
+ // false positives in the ops sanitizer). We should probably rewrite sanitizers
+ // to be done in Rust instead of in JS (40_testing.js).
+ {
+ // Poll event loop once, this will allow all ops that are already resolved,
+ // but haven't responded to settle.
+ let waker = noop_waker();
+ let mut cx = Context::from_waker(&waker);
+ let _ = worker.js_runtime.poll_event_loop(&mut cx, false);
+ }
+
let earlier = SystemTime::now();
let result = match worker.js_runtime.call_and_await(&function).await {
Ok(r) => r,