'use strict'; const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); const assert = require('assert'); const http2 = require('http2'); const makeDuplexPair = require('../common/duplexpair'); const { parentPort, Worker } = require('worker_threads'); // This test ensures that workers can be terminated without error while // stream activity is ongoing, in particular the C++ function // ReportWritesToJSStreamListener::OnStreamAfterReqFinished. const MAX_ITERATIONS = 5; const MAX_THREADS = 6; // Do not use isMainThread so that this test itself can be run inside a Worker. if (!process.env.HAS_STARTED_WORKER) { process.env.HAS_STARTED_WORKER = 1; function spinWorker(iter) { const w = new Worker(__filename); w.on('message', common.mustCall((msg) => { assert.strictEqual(msg, 'terminate'); w.terminate(); })); w.on('exit', common.mustCall(() => { if (iter < MAX_ITERATIONS) spinWorker(++iter); })); } for (let i = 0; i < MAX_THREADS; i++) { spinWorker(0); } } else { const server = http2.createServer(); let i = 0; server.on('stream', (stream, headers) => { if (i === 1) { parentPort.postMessage('terminate'); } i++; stream.end(''); }); const { clientSide, serverSide } = makeDuplexPair(); server.emit('connection', serverSide); const client = http2.connect('http://localhost:80', { createConnection: () => clientSide, }); function makeRequests() { for (let i = 0; i < 3; i++) { client.request().end(); } setImmediate(makeRequests); } makeRequests(); }