diff options
author | Ryan Dahl <ry@tinyclouds.org> | 2019-03-10 15:37:05 -0400 |
---|---|---|
committer | Ryan Dahl <ry@tinyclouds.org> | 2019-03-12 19:25:57 -0400 |
commit | 58cc69f672f91841984fc4e1e9bcfb1a75362677 (patch) | |
tree | a3e50ff11dfe8348c6574eeedcd2577e3690b440 /js/timers.ts | |
parent | 9691d7b53bea5a2656ec47e8437fac1f527b3cce (diff) |
Make timers act like normal ops
This is in preperation for core integration.
Diffstat (limited to 'js/timers.ts')
-rw-r--r-- | js/timers.ts | 56 |
1 files changed, 32 insertions, 24 deletions
diff --git a/js/timers.ts b/js/timers.ts index d06056cf2..4089d5f8b 100644 --- a/js/timers.ts +++ b/js/timers.ts @@ -2,7 +2,7 @@ import { assert } from "./util"; import * as msg from "gen/msg_generated"; import * as flatbuffers from "./flatbuffers"; -import { sendSync, setFireTimersCallback } from "./dispatch"; +import { sendAsync, sendSync } from "./dispatch"; interface Timer { id: number; @@ -37,28 +37,39 @@ function getTime(): number { return now; } -function setGlobalTimeout(due: number | null, now: number): void { +function clearGlobalTimeout(): void { + const builder = flatbuffers.createBuilder(); + msg.GlobalTimerStop.startGlobalTimerStop(builder); + const inner = msg.GlobalTimerStop.endGlobalTimerStop(builder); + globalTimeoutDue = null; + let res = sendSync(builder, msg.Any.GlobalTimerStop, inner); + assert(res == null); +} + +async function setGlobalTimeout(due: number, now: number): Promise<void> { // Since JS and Rust don't use the same clock, pass the time to rust as a // relative time value. On the Rust side we'll turn that into an absolute // value again. - // Note that a negative time-out value stops the global timer. - let timeout; - if (due === null) { - timeout = -1; - } else { - timeout = due - now; - assert(timeout >= 0); - } + let timeout = due - now; + assert(timeout >= 0); // Send message to the backend. const builder = flatbuffers.createBuilder(); - msg.SetTimeout.startSetTimeout(builder); - msg.SetTimeout.addTimeout(builder, timeout); - const inner = msg.SetTimeout.endSetTimeout(builder); - const res = sendSync(builder, msg.Any.SetTimeout, inner); - assert(res == null); - // Remember when when the global timer will fire. + msg.GlobalTimer.startGlobalTimer(builder); + msg.GlobalTimer.addTimeout(builder, timeout); + const inner = msg.GlobalTimer.endGlobalTimer(builder); globalTimeoutDue = due; + await sendAsync(builder, msg.Any.GlobalTimer, inner); + // eslint-disable-next-line @typescript-eslint/no-use-before-define + fireTimers(); +} + +function setOrClearGlobalTimeout(due: number | null, now: number): void { + if (due == null) { + clearGlobalTimeout(); + } else { + setGlobalTimeout(due, now); + } } function schedule(timer: Timer, now: number): void { @@ -75,7 +86,7 @@ function schedule(timer: Timer, now: number): void { // If the new timer is scheduled to fire before any timer that existed before, // update the global timeout to reflect this. if (globalTimeoutDue === null || globalTimeoutDue > timer.due) { - setGlobalTimeout(timer.due, now); + setOrClearGlobalTimeout(timer.due, now); } } @@ -97,7 +108,7 @@ function unschedule(timer: Timer): void { nextTimerDue = Number(key); break; } - setGlobalTimeout(nextTimerDue, getTime()); + setOrClearGlobalTimeout(nextTimerDue, getTime()); } } else { // Multiple timers that are due at the same point in time. @@ -162,9 +173,10 @@ function fireTimers(): void { Promise.resolve(timer).then(fire); } } + // Update the global alarm to go off when the first-up timer that hasn't fired // yet is due. - setGlobalTimeout(nextTimerDue, now); + setOrClearGlobalTimeout(nextTimerDue, now); } export type Args = unknown[]; @@ -226,7 +238,7 @@ export function setInterval( return setTimer(cb, delay, args, true); } -/** Clears a previously set timer by id. */ +/** Clears a previously set timer by id. AKA clearTimeout and clearInterval. */ export function clearTimer(id: number): void { const timer = idMap.get(id); if (timer === undefined) { @@ -237,7 +249,3 @@ export function clearTimer(id: number): void { unschedule(timer); idMap.delete(timer.id); } - -// Tell the dispatcher which function it should call to fire timers that are -// due. This is done using a callback because circular imports are disallowed. -setFireTimersCallback(fireTimers); |