Skip to content

Commit

Permalink
timers: allow passing delay to timer.refresh()
Browse files Browse the repository at this point in the history
  • Loading branch information
mscdex committed Oct 12, 2021
1 parent c350c21 commit 7ddac5c
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 9 deletions.
2 changes: 1 addition & 1 deletion doc/api/deprecations.md
Original file line number Diff line number Diff line change
Expand Up @@ -2952,7 +2952,7 @@ it was an aborted or graceful destroy.
[`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
Expand Down
16 changes: 12 additions & 4 deletions doc/api/timers.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,17 +105,25 @@ 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]])`
<!-- YAML
added: v10.2.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/xxxx
description: Added `delay` and `resetInterval` parameters.
-->

* `delay` {number} The number of milliseconds to wait before calling the
original callback. **Default:** `1`.
* `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.
Expand Down
20 changes: 16 additions & 4 deletions lib/internal/timers.js
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,7 @@ function initAsyncResource(resource, type) {
emitInit(asyncId, type, triggerAsyncId, resource);
}

// Timer constructor function.
// The entire prototype is defined in lib/timers.js
function Timeout(callback, after, args, isRepeat, isRefed) {
function calcAfter(after) {
after *= 1; // Coalesce to number or NaN
if (!(after >= 1 && after <= TIMEOUT_MAX)) {
if (after > TIMEOUT_MAX) {
Expand All @@ -175,6 +173,13 @@ function Timeout(callback, after, args, isRepeat, isRefed) {
}
after = 1; // Schedule on next tick, follows browser behavior
}
return after;
}

// Timer constructor function.
// The entire prototype is defined in lib/timers.js
function Timeout(callback, after, args, isRepeat, isRefed) {
after = calcAfter(after);

this._idleTimeout = after;
this._idlePrev = this;
Expand Down Expand Up @@ -207,7 +212,14 @@ Timeout.prototype[inspect.custom] = function(_, options) {
});
};

Timeout.prototype.refresh = function() {
Timeout.prototype.refresh = function(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
Expand Down
28 changes: 28 additions & 0 deletions test/sequential/test-timers-refresh-args.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
'use strict';
require('../common');
const assert = require('assert');

let last;
let t = setTimeout(() => {
if (last !== undefined) {
assert(Date.now() - last < 200);

last = undefined;
let count = 0;
t = setInterval(() => {
if (last !== undefined)
assert(Date.now() - last < 200);
last = Date.now();
switch (count++) {
case 0:
t.refresh(100, true);
case 3:
clearInterval(t);
return;
}
}, 200);
return;
}
last = Date.now();
t.refresh(100);
}, 200);

0 comments on commit 7ddac5c

Please sign in to comment.