node/test/parallel/test-abortsignal-cloneable.js

79 lines
2.2 KiB
JavaScript
Raw Normal View History

'use strict';
const common = require('../common');
const { ok, strictEqual } = require('assert');
const { setImmediate: pause } = require('timers/promises');
function deferred() {
let res;
const promise = new Promise((resolve) => res = resolve);
return { res, promise };
}
(async () => {
const ac = new AbortController();
const mc = new MessageChannel();
const deferred1 = deferred();
const deferred2 = deferred();
const resolvers = [deferred1, deferred2];
mc.port1.onmessage = common.mustCall(({ data }) => {
data.addEventListener('abort', common.mustCall(() => {
strictEqual(data.reason, 'boom');
}));
resolvers.shift().res();
}, 2);
mc.port2.postMessage(ac.signal, [ac.signal]);
// Can be cloned/transferd multiple times and they all still work
mc.port2.postMessage(ac.signal, [ac.signal]);
mc.port2.close();
// Although we're using transfer semantics, the local AbortSignal
// is still usable locally.
ac.signal.addEventListener('abort', common.mustCall(() => {
strictEqual(ac.signal.reason, 'boom');
}));
await Promise.all([ deferred1.promise, deferred2.promise ]);
ac.abort('boom');
// Because the postMessage used by the underlying AbortSignal
// takes at least one turn of the event loop to be processed,
// and because it is unref'd, it won't, by itself, keep the
// event loop open long enough for the test to complete, so
// we schedule two back to back turns of the event to ensure
// the loop runs long enough for the test to complete.
await pause();
await pause();
})().then(common.mustCall());
{
const signal = AbortSignal.abort('boom');
ok(signal.aborted);
strictEqual(signal.reason, 'boom');
const mc = new MessageChannel();
mc.port1.onmessage = common.mustCall(({ data }) => {
ok(data instanceof AbortSignal);
ok(data.aborted);
strictEqual(data.reason, 'boom');
mc.port1.close();
});
mc.port2.postMessage(signal, [signal]);
}
{
// The cloned AbortSignal does not keep the event loop open
// waiting for the abort to be triggered.
const ac = new AbortController();
const mc = new MessageChannel();
mc.port1.onmessage = common.mustCall();
mc.port2.postMessage(ac.signal, [ac.signal]);
mc.port2.close();
}