timers: make timer.refresh() a public API

Originally added in
bb5575aa75fd3071724d5eccde39a3041e1af57a
discussions such as
https://github.com/nodejs/node/issues/20261
show the usefulness of this API to the Node.js ecosystem.

PR-URL: https://github.com/nodejs/node/pull/20298

Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Ujjwal Sharma <usharma1998@gmail.com>
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com>
This commit is contained in:
Jeremiah Senkpiel 2018-04-25 12:45:34 -04:00 committed by Ujjwal Sharma
parent d942573393
commit 46d335c380
No known key found for this signature in database
GPG Key ID: 1FD3B47B83F46621
5 changed files with 44 additions and 14 deletions

View File

@ -74,6 +74,21 @@ 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()
<!-- YAML
added: REPLACEME
-->
* 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.
Using this on a timer that has already called its callback will reactivate the
timer.
### timeout.unref()
<!-- YAML
added: v0.9.1

View File

@ -107,8 +107,7 @@ const {
const {
kTimeout,
setUnrefTimeout,
validateTimerDuration,
refreshFnSymbol
validateTimerDuration
} = require('internal/timers');
const {
createWriteWrap,
@ -962,7 +961,7 @@ class Http2Session extends EventEmitter {
[kUpdateTimer]() {
if (this.destroyed)
return;
if (this[kTimeout]) this[kTimeout][refreshFnSymbol]();
if (this[kTimeout]) this[kTimeout].refresh();
}
// Sets the id of the next stream to be created by this Http2Session.
@ -1539,7 +1538,7 @@ class Http2Stream extends Duplex {
if (this.destroyed)
return;
if (this[kTimeout])
this[kTimeout][refreshFnSymbol]();
this[kTimeout].refresh();
if (this[kSession])
this[kSession][kUpdateTimer]();
}

View File

@ -19,7 +19,6 @@ const {
// Timeout values > TIMEOUT_MAX are set to 1.
const TIMEOUT_MAX = 2 ** 31 - 1;
const refreshFnSymbol = Symbol('refresh()');
const unrefedSymbol = Symbol('unrefed');
module.exports = {
@ -29,7 +28,6 @@ module.exports = {
trigger_async_id_symbol,
Timeout,
initAsyncResource,
refreshFnSymbol,
setUnrefTimeout,
validateTimerDuration
};
@ -82,7 +80,7 @@ function Timeout(callback, after, args, isRepeat, isUnrefed) {
initAsyncResource(this, 'Timeout');
}
Timeout.prototype[refreshFnSymbol] = function refresh() {
Timeout.prototype.refresh = function() {
if (this._handle) {
// Would be more ideal with uv_timer_again(), however that API does not
// cause libuv's sorted timers data structure (a binary heap at the time
@ -93,6 +91,8 @@ Timeout.prototype[refreshFnSymbol] = function refresh() {
} else {
getTimers().active(this);
}
return this;
};
function setUnrefTimeout(callback, after, arg1, arg2, arg3) {

View File

@ -89,8 +89,7 @@ const exceptionWithHostPort = errors.exceptionWithHostPort;
const {
kTimeout,
setUnrefTimeout,
validateTimerDuration,
refreshFnSymbol
validateTimerDuration
} = require('internal/timers');
function noop() {}
@ -325,7 +324,7 @@ util.inherits(Socket, stream.Duplex);
Socket.prototype._unrefTimer = function _unrefTimer() {
for (var s = this; s !== null; s = s._parent) {
if (s[kTimeout])
s[kTimeout][refreshFnSymbol]();
s[kTimeout].refresh();
}
};

View File

@ -5,7 +5,7 @@
const common = require('../common');
const { strictEqual } = require('assert');
const { setUnrefTimeout, refreshFnSymbol } = require('internal/timers');
const { setUnrefTimeout } = require('internal/timers');
// Schedule the unrefed cases first so that the later case keeps the event loop
// active.
@ -27,7 +27,7 @@ const { setUnrefTimeout, refreshFnSymbol } = require('internal/timers');
strictEqual(called, false, 'unref()\'d timer returned before check');
}), 1);
timer[refreshFnSymbol]();
strictEqual(timer.refresh(), timer);
}
// unref pooled timer
@ -41,7 +41,7 @@ const { setUnrefTimeout, refreshFnSymbol } = require('internal/timers');
strictEqual(called, false, 'unref pooled timer returned before check');
}), 1);
timer[refreshFnSymbol]();
strictEqual(timer.refresh(), timer);
}
// regular timer
@ -55,5 +55,22 @@ const { setUnrefTimeout, refreshFnSymbol } = require('internal/timers');
strictEqual(called, false, 'pooled timer returned before check');
}), 1);
timer[refreshFnSymbol]();
strictEqual(timer.refresh(), timer);
}
// interval
{
let called = 0;
const timer = setInterval(common.mustCall(() => {
called += 1;
if (called === 2) {
clearInterval(timer);
}
}, 2), 1);
setTimeout(common.mustCall(() => {
strictEqual(called, 0, 'pooled timer returned before check');
}), 1);
strictEqual(timer.refresh(), timer);
}