From 4ed6584091736fcb7a45158b6e1c91f997f15164 Mon Sep 17 00:00:00 2001 From: Brian White Date: Tue, 12 Oct 2021 19:06:34 -0400 Subject: [PATCH] timers: allow passing delay to timer.refresh() --- doc/api/deprecations.md | 2 +- doc/api/timers.md | 16 +++++++--- lib/internal/timers.js | 35 ++++++++++++++------- test/sequential/test-timers-refresh-args.js | 31 ++++++++++++++++++ 4 files changed, 68 insertions(+), 16 deletions(-) create mode 100644 test/sequential/test-timers-refresh-args.js diff --git a/doc/api/deprecations.md b/doc/api/deprecations.md index 4577538251015e..4e489868c476a8 100644 --- a/doc/api/deprecations.md +++ b/doc/api/deprecations.md @@ -3242,7 +3242,7 @@ Convert them to primitive strings. [`setTimeout()`]: timers.md#settimeoutcallback-delay-args [`socket.bufferSize`]: net.md#socketbuffersize [`timeout.ref()`]: timers.md#timeoutref -[`timeout.refresh()`]: timers.md#timeoutrefresh +[`timeout.refresh()`]: timers.md#timeoutrefreshdelay-resetinterval [`timeout.unref()`]: timers.md#timeoutunref [`tls.CryptoStream`]: tls.md#class-tlscryptostream [`tls.SecureContext`]: tls.md#tlscreatesecurecontextoptions diff --git a/doc/api/timers.md b/doc/api/timers.md index d054ad7d419c32..c04cc9edbf5a8c 100644 --- a/doc/api/timers.md +++ b/doc/api/timers.md @@ -111,18 +111,26 @@ When called, requests that the Node.js event loop _not_ exit so long as the By default, all `Timeout` objects are "ref'ed", making it normally unnecessary to call `timeout.ref()` unless `timeout.unref()` had been called previously. -### `timeout.refresh()` +### `timeout.refresh([delay[, resetInterval]])` +* `delay` {number} The number of milliseconds to wait before calling the + original callback. +* `resetInterval` {boolean} For an interval timer, should the interval be set to + `delay`? **Default:** `false`. * Returns: {Timeout} a reference to `timeout` Sets the timer's start time to the current time, and reschedules the timer to -call its callback at the previously specified duration adjusted to the current -time. This is useful for refreshing a timer without allocating a new -JavaScript object. +call its callback at the previously specified duration or the duration specified +by `delay` adjusted to the current time. This is useful for refreshing a timer +without allocating a new JavaScript object. Using this on a timer that has already called its callback will reactivate the timer. diff --git a/lib/internal/timers.js b/lib/internal/timers.js index a2a1c1e387bf6a..f339e5b4ce9c45 100644 --- a/lib/internal/timers.js +++ b/lib/internal/timers.js @@ -158,20 +158,26 @@ function initAsyncResource(resource, type) { if (initHooksExist()) emitInit(asyncId, type, triggerAsyncId, resource); } + +function calcAfter(after) { + after *= 1; // Coalesce to number or NaN + if (!(after >= 1 && after <= TIMEOUT_MAX)) { + if (after > TIMEOUT_MAX) { + process.emitWarning(`${after} does not fit into` + + ' a 32-bit signed integer.' + + '\nTimeout duration was set to 1.', + 'TimeoutOverflowWarning'); + } + after = 1; // Schedule on next tick, follows browser behavior + } + return after; +} + class Timeout { // Timer constructor function. // The entire prototype is defined in lib/timers.js constructor(callback, after, args, isRepeat, isRefed) { - after *= 1; // Coalesce to number or NaN - if (!(after >= 1 && after <= TIMEOUT_MAX)) { - if (after > TIMEOUT_MAX) { - process.emitWarning(`${after} does not fit into` + - ' a 32-bit signed integer.' + - '\nTimeout duration was set to 1.', - 'TimeoutOverflowWarning'); - } - after = 1; // Schedule on next tick, follows browser behavior - } + after = calcAfter(after); this._idleTimeout = after; this._idlePrev = this; @@ -204,7 +210,14 @@ class Timeout { }); } - refresh() { + refresh(after, resetInterval) { + if (after !== undefined) { + after = calcAfter(after); + this._idleTimeout = after; + if (this._repeat !== null && resetInterval) + this._repeat = after; + } + if (this[kRefed]) active(this); else diff --git a/test/sequential/test-timers-refresh-args.js b/test/sequential/test-timers-refresh-args.js new file mode 100644 index 00000000000000..b8c8906d63c935 --- /dev/null +++ b/test/sequential/test-timers-refresh-args.js @@ -0,0 +1,31 @@ +'use strict'; +require('../common'); +const assert = require('assert'); + +const LONGER_DELAY = 1000; +const SHORTER_DELAY = 100; +let last; +let t = setTimeout(() => { + if (last !== undefined) { + assert(Date.now() - last < LONGER_DELAY); + + last = undefined; + let count = 0; + t = setInterval(() => { + if (last !== undefined) + assert(Date.now() - last < LONGER_DELAY); + last = Date.now(); + switch (count++) { + case 0: + t.refresh(SHORTER_DELAY, true); + break; + case 3: + clearInterval(t); + break; + } + }, LONGER_DELAY); + return; + } + last = Date.now(); + t.refresh(SHORTER_DELAY); +}, LONGER_DELAY);