1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-25 00:29:09 -05:00

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.
This commit is contained in:
Divy Srivastava 2022-10-17 04:29:16 -07:00 committed by GitHub
parent e41af14b2a
commit 4c9dd33e27
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 12 additions and 14 deletions

View file

@ -18,7 +18,6 @@
// deno-lint-ignore camelcase // deno-lint-ignore camelcase
NumberPOSITIVE_INFINITY, NumberPOSITIVE_INFINITY,
PromisePrototypeThen, PromisePrototypeThen,
ObjectPrototypeIsPrototypeOf,
SafeArrayIterator, SafeArrayIterator,
SymbolFor, SymbolFor,
TypeError, TypeError,
@ -245,7 +244,12 @@
// 1. // 1.
PromisePrototypeThen( PromisePrototypeThen(
sleepPromise, sleepPromise,
() => { (cancelled) => {
if (!cancelled) {
// The timer was cancelled.
removeFromScheduledTimers(timerObject);
return;
}
// 2. Wait until any invocations of this algorithm that had the same // 2. Wait until any invocations of this algorithm that had the same
// global and orderingIdentifier, that started before this one, and // global and orderingIdentifier, that started before this one, and
// whose milliseconds is equal to or less than this one's, have // whose milliseconds is equal to or less than this one's, have
@ -278,14 +282,6 @@
currentEntry = currentEntry.next; currentEntry = currentEntry.next;
} }
}, },
(err) => {
if (ObjectPrototypeIsPrototypeOf(core.InterruptedPrototype, err)) {
// The timer was cancelled.
removeFromScheduledTimers(timerObject);
} else {
throw err;
}
},
); );
} }

View file

@ -77,15 +77,17 @@ pub fn op_timer_handle(state: &mut OpState) -> ResourceId {
/// Waits asynchronously until either `millis` milliseconds have passed or the /// Waits asynchronously until either `millis` milliseconds have passed or the
/// [`TimerHandle`] resource given by `rid` has been canceled. /// [`TimerHandle`] resource given by `rid` has been canceled.
///
/// If the timer is canceled, this returns `false`. Otherwise, it returns `true`.
#[op(deferred)] #[op(deferred)]
pub async fn op_sleep( pub async fn op_sleep(
state: Rc<RefCell<OpState>>, state: Rc<RefCell<OpState>>,
millis: u64, millis: u64,
rid: ResourceId, rid: ResourceId,
) -> Result<(), AnyError> { ) -> Result<bool, AnyError> {
let handle = state.borrow().resource_table.get::<TimerHandle>(rid)?; let handle = state.borrow().resource_table.get::<TimerHandle>(rid)?;
tokio::time::sleep(Duration::from_millis(millis)) let res = tokio::time::sleep(Duration::from_millis(millis))
.or_cancel(handle.0.clone()) .or_cancel(handle.0.clone())
.await?; .await;
Ok(()) Ok(res.is_ok())
} }