From 4c9dd33e27d31a0f6f8f26e043fbfbefa84db0f2 Mon Sep 17 00:00:00 2001 From: Divy Srivastava Date: Mon, 17 Oct 2022 04:29:16 -0700 Subject: [PATCH] perf(ext/web): optimize timer cancellation (#16316) Towards #16315 It created a bunch of Error objects and rejected the promise. This patch changes `op_sleep` to resolve with `true` if it was cancelled. --- ext/web/02_timers.js | 16 ++++++---------- ext/web/timers.rs | 10 ++++++---- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/ext/web/02_timers.js b/ext/web/02_timers.js index 7c0bc1e3a7..0fc8087966 100644 --- a/ext/web/02_timers.js +++ b/ext/web/02_timers.js @@ -18,7 +18,6 @@ // deno-lint-ignore camelcase NumberPOSITIVE_INFINITY, PromisePrototypeThen, - ObjectPrototypeIsPrototypeOf, SafeArrayIterator, SymbolFor, TypeError, @@ -245,7 +244,12 @@ // 1. PromisePrototypeThen( sleepPromise, - () => { + (cancelled) => { + if (!cancelled) { + // The timer was cancelled. + removeFromScheduledTimers(timerObject); + return; + } // 2. Wait until any invocations of this algorithm that had the same // global and orderingIdentifier, that started before this one, and // whose milliseconds is equal to or less than this one's, have @@ -278,14 +282,6 @@ currentEntry = currentEntry.next; } }, - (err) => { - if (ObjectPrototypeIsPrototypeOf(core.InterruptedPrototype, err)) { - // The timer was cancelled. - removeFromScheduledTimers(timerObject); - } else { - throw err; - } - }, ); } diff --git a/ext/web/timers.rs b/ext/web/timers.rs index ba5e12d62d..5b13107928 100644 --- a/ext/web/timers.rs +++ b/ext/web/timers.rs @@ -77,15 +77,17 @@ pub fn op_timer_handle(state: &mut OpState) -> ResourceId { /// Waits asynchronously until either `millis` milliseconds have passed or the /// [`TimerHandle`] resource given by `rid` has been canceled. +/// +/// If the timer is canceled, this returns `false`. Otherwise, it returns `true`. #[op(deferred)] pub async fn op_sleep( state: Rc>, millis: u64, rid: ResourceId, -) -> Result<(), AnyError> { +) -> Result { let handle = state.borrow().resource_table.get::(rid)?; - tokio::time::sleep(Duration::from_millis(millis)) + let res = tokio::time::sleep(Duration::from_millis(millis)) .or_cancel(handle.0.clone()) - .await?; - Ok(()) + .await; + Ok(res.is_ok()) }