Skip to content

Commit

Permalink
timers: support Symbol.dispose
Browse files Browse the repository at this point in the history
PR-URL: #48633
Reviewed-By: Zeyu "Alex" Yang <[email protected]>
Reviewed-By: Benjamin Gruenbaum <[email protected]>
Reviewed-By: Robert Nagy <[email protected]>
  • Loading branch information
MoLow authored Jul 5, 2023
1 parent 6fda81d commit 56b8de1
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 1 deletion.
20 changes: 20 additions & 0 deletions doc/api/timers.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,16 @@ loop to remain active. If there is no other activity keeping the event loop
running, the process may exit before the `Immediate` object's callback is
invoked. Calling `immediate.unref()` multiple times will have no effect.

### `immediate[Symbol.dispose]()`

<!-- YAML
added: REPLACEME
-->

> Stability: 1 - Experimental
Cancels the immediate. This is similar to calling `clearImmediate()`.

## Class: `Timeout`

This object is created internally and is returned from [`setTimeout()`][] and
Expand Down Expand Up @@ -157,6 +167,16 @@ across [`worker_threads`][] it must first be passed to the correct
thread. This allows enhanced compatibility with browser
`setTimeout()` and `setInterval()` implementations.

### `timeout[Symbol.dispose]()`

<!-- YAML
added: REPLACEME
-->

> Stability: 1 - Experimental
Cancels the timeout.

## Scheduling timers

A timer in Node.js is an internal construct that calls a given function after
Expand Down
2 changes: 1 addition & 1 deletion lib/internal/per_context/primordials.js
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ function copyPrototype(src, dest, prefix) {
copyPrototype(original.prototype, primordials, `${name}Prototype`);
});

// Define Symbol.Dispose and Symbol.AsyncDispose
// Define Symbol.dispose and Symbol.asyncDispose
// Until these are defined by the environment.
// TODO(MoLow): Remove this polyfill once Symbol.dispose and Symbol.asyncDispose are available in V8.
primordials.SymbolDispose ??= primordials.SymbolFor('nodejs.dispose');
Expand Down
9 changes: 9 additions & 0 deletions lib/timers.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
const {
MathTrunc,
ObjectDefineProperty,
SymbolDispose,
SymbolToPrimitive,
} = primordials;

Expand Down Expand Up @@ -253,6 +254,10 @@ Timeout.prototype.close = function() {
return this;
};

Timeout.prototype[SymbolDispose] = function() {
clearTimeout(this);
};

/**
* Coerces a `Timeout` to a primitive.
* @returns {number}
Expand Down Expand Up @@ -338,6 +343,10 @@ function clearImmediate(immediate) {
immediateQueue.remove(immediate);
}

Immediate.prototype[SymbolDispose] = function() {
clearImmediate(this);
};

module.exports = {
setTimeout,
clearTimeout,
Expand Down
18 changes: 18 additions & 0 deletions test/parallel/test-timers-dispose.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
'use strict';
const common = require('../common');
const assert = require('assert');

const timer = setTimeout(common.mustNotCall(), 10);
const interval = setInterval(common.mustNotCall(), 10);
const immediate = setImmediate(common.mustNotCall());

timer[Symbol.dispose]();
interval[Symbol.dispose]();
immediate[Symbol.dispose]();


process.on('exit', () => {
assert.strictEqual(timer._destroyed, true);
assert.strictEqual(interval._destroyed, true);
assert.strictEqual(immediate._destroyed, true);
});

0 comments on commit 56b8de1

Please sign in to comment.