Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(node): add Timeout class #1699

Merged
merged 10 commits into from
Jan 19, 2022
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
897 changes: 897 additions & 0 deletions node/_http_client.js

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions node/_tools/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,17 @@
"test-stream3-cork-uncork.js",
"test-stream3-pause-then-read.js",
"test-streams-highwatermark.js",
"test-timers-api-refs.js",
"test-timers-args.js",
"test-timers-clear-null-does-not-throw-error.js",
"test-timers-clear-object-does-not-throw-error.js",
"test-timers-clear-timeout-interval-equivalent.js",
"test-timers-clearImmediate.js",
"test-timers-non-integer-delay.js",
"test-timers-same-timeout-wrong-list-deleted.js",
"test-timers-timeout-with-non-integer.js",
"test-timers-user-call.js",
"test-timers-zero-timeout.js",
"test-url-fileurltopath.js",
"test-url-format-whatwg.js",
"test-url-parse-format.js",
Expand Down
28 changes: 28 additions & 0 deletions node/_tools/suites/parallel/test-timers-api-refs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file

// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 16.13.0
// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually

'use strict';
const common = require('../common');
const timers = require('timers');

// Delete global APIs to make sure they're not relied on by the internal timers
// code
delete global.setTimeout;
delete global.clearTimeout;
delete global.setInterval;
delete global.clearInterval;
delete global.setImmediate;
delete global.clearImmediate;

const timeoutCallback = () => { timers.clearTimeout(timeout); };
const timeout = timers.setTimeout(common.mustCall(timeoutCallback), 1);

const intervalCallback = () => { timers.clearInterval(interval); };
const interval = timers.setInterval(common.mustCall(intervalCallback), 1);

const immediateCallback = () => { timers.clearImmediate(immediate); };
const immediate = timers.setImmediate(immediateCallback);
38 changes: 38 additions & 0 deletions node/_tools/suites/parallel/test-timers-args.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file

// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 16.13.0
// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually

'use strict';
require('../common');
const assert = require('assert');

function range(n) {
return 'x'.repeat(n + 1).split('').map(function(_, i) { return i; });
}

function timeout(nargs) {
const args = range(nargs);
setTimeout.apply(null, [callback, 1].concat(args));

function callback() {
assert.deepStrictEqual([].slice.call(arguments), args);
if (nargs < 128) timeout(nargs + 1);
}
}

function interval(nargs) {
const args = range(nargs);
const timer = setTimeout.apply(null, [callback, 1].concat(args));

function callback() {
clearInterval(timer);
assert.deepStrictEqual([].slice.call(arguments), args);
if (nargs < 128) interval(nargs + 1);
}
}

timeout(0);
interval(0);
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file

// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 16.13.0
// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually

'use strict';
require('../common');

// This test makes sure clearing timers with
// 'null' or no input does not throw error
clearInterval(null);
clearInterval();
clearTimeout(null);
clearTimeout();
clearImmediate(null);
clearImmediate();
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file

// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 16.13.0
// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually

'use strict';
require('../common');

// This test makes sure clearing timers with
// objects doesn't throw
clearImmediate({});
clearTimeout({});
clearInterval({});
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file

// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 16.13.0
// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually

'use strict';
const common = require('../common');

// This test makes sure that timers created with setTimeout can be disarmed by
// clearInterval and that timers created with setInterval can be disarmed by
// clearTimeout.
//
// This behavior is documented in the HTML Living Standard:
//
// * Refs: https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-setinterval

// Disarm interval with clearTimeout.
const interval = setInterval(common.mustNotCall(), 1);
clearTimeout(interval);

// Disarm timeout with clearInterval.
const timeout = setTimeout(common.mustNotCall(), 1);
clearInterval(timeout);
20 changes: 20 additions & 0 deletions node/_tools/suites/parallel/test-timers-clearImmediate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file

// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 16.13.0
// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually

'use strict';
const common = require('../common');

const N = 3;

function next() {
const fn = common.mustCall(() => clearImmediate(immediate));
const immediate = setImmediate(fn);
}

for (let i = 0; i < N; i++) {
next();
}
88 changes: 88 additions & 0 deletions node/_tools/suites/parallel/test-timers-non-integer-delay.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file

// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 16.13.0
// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually

// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

'use strict';
const common = require('../common');
const assert = require('assert');

// This test makes sure that non-integer timer delays do not make the process
// hang. See https://github.com/joyent/node/issues/8065 and
// https://github.com/joyent/node/issues/8068 which have been fixed by
// https://github.com/joyent/node/pull/8073.
//
// If the process hangs, this test will make the tests suite timeout,
// otherwise it will exit very quickly (after 50 timers with a short delay
// fire).
//
// We have to set at least several timers with a non-integer delay to
// reproduce the issue. Sometimes, a timer with a non-integer delay will
// expire correctly. 50 timers has always been more than enough to reproduce
// it 100%.

const TIMEOUT_DELAY = 1.1;
let N = 50;

const interval = setInterval(common.mustCall(() => {
if (--N === 0) {
clearInterval(interval);
}
}, N), TIMEOUT_DELAY);

// Test non-integer delay ordering
{
const ordering = [];

setTimeout(common.mustCall(() => {
ordering.push(1);
}), 1);

setTimeout(common.mustCall(() => {
ordering.push(2);
}), 1.8);

setTimeout(common.mustCall(() => {
ordering.push(3);
}), 1.1);

setTimeout(common.mustCall(() => {
ordering.push(4);
}), 1);

setTimeout(common.mustCall(() => {
const expected = [1, 2, 3, 4];

assert.deepStrictEqual(
ordering,
expected,
`Non-integer delay ordering should be ${expected}, but got ${ordering}`
);

// 2 should always be last of these delays due to ordering guarantees by
// the implementation.
}), 2);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file

// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 16.13.0
// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually

'use strict';

// This is a regression test for https://github.com/nodejs/node/issues/7722.
//
// When nested timers have the same timeout, calling clearTimeout on the
// older timer after it has fired causes the list the newer timer is in
// to be deleted. Since the newer timer was not cleared, it still blocks
// the event loop completing for the duration of its timeout, however, since
// no reference exists to it in its list, it cannot be canceled and its
// callback is not called when the timeout elapses.

const common = require('../common');

const TIMEOUT = common.platformTimeout(100);

const handle1 = setTimeout(common.mustCall(function() {
// Cause the old TIMEOUT list to be deleted
clearTimeout(handle1);

// Cause a new list with the same key (TIMEOUT) to be created for this timer
const handle2 = setTimeout(common.mustNotCall(), TIMEOUT);

setTimeout(common.mustCall(function() {
// Attempt to cancel the second timer. Fix for this bug will keep the
// newer timer from being dereferenced by keeping its list from being
// erroneously deleted. If we are able to cancel the timer successfully,
// the bug is fixed.
clearTimeout(handle2);
}), 1);

// When this callback completes, `listOnTimeout` should now look at the
// correct list and refrain from removing the new TIMEOUT list which
// contains the reference to the newer timer.
}), TIMEOUT);
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file

// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 16.13.0
// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually

'use strict';
const common = require('../common');

/**
* This test is for https://github.com/nodejs/node/issues/24203
*/
let count = 50;
const time = 1.00000000000001;
const exec = common.mustCall(() => {
if (--count === 0) {
return;
}
setTimeout(exec, time);
}, count);
exec();
47 changes: 47 additions & 0 deletions node/_tools/suites/parallel/test-timers-user-call.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file

// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 16.13.0
// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually

// Make sure `setTimeout()` and friends don't throw if the user-supplied
// function has .call() and .apply() monkey-patched to undesirable values.

// Refs: https://github.com/nodejs/node/issues/12956

'use strict';

const common = require('../common');

{
const fn = common.mustCall(10);
fn.call = 'not a function';
fn.apply = 'also not a function';
setTimeout(fn, 1);
setTimeout(fn, 1, 'oneArg');
setTimeout(fn, 1, 'two', 'args');
setTimeout(fn, 1, 'three', '(3)', 'args');
setTimeout(fn, 1, 'more', 'than', 'three', 'args');

setImmediate(fn, 1);
setImmediate(fn, 1, 'oneArg');
setImmediate(fn, 1, 'two', 'args');
setImmediate(fn, 1, 'three', '(3)', 'args');
setImmediate(fn, 1, 'more', 'than', 'three', 'args');
}

{
const testInterval = (...args) => {
const fn = common.mustCall(() => { clearInterval(interval); });
fn.call = 'not a function';
fn.apply = 'also not a function';
const interval = setInterval(fn, 1, ...args);
};

testInterval();
testInterval('oneArg');
testInterval('two', 'args');
testInterval('three', '(3)', 'args');
testInterval('more', 'than', 'three', 'args');
}
Loading