diff --git a/eslint.config.js b/eslint.config.js index b5f4c78..5cc76a8 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -56,7 +56,6 @@ export default defineConfig([ { // TODO: Must-have rules. Enable one-by-one rules: { - '@typescript-eslint/no-floating-promises': 'off', '@typescript-eslint/no-misused-promises': 'off', '@typescript-eslint/ban-ts-comment': 'off', '@typescript-eslint/ban-types': 'off', diff --git a/src/index.ts b/src/index.ts index e4dd4af..94d9345 100644 --- a/src/index.ts +++ b/src/index.ts @@ -493,7 +493,7 @@ class WorkerInfo extends AsynchronouslyCreatedResource { ) : null - this.worker.terminate().then(() => { + void this.worker.terminate().then(() => { if (timer !== null) { clearTimeout(timer) } @@ -791,7 +791,7 @@ class ThreadPool { // Remove the worker from the list and potentially start a new Worker to // replace the current one. - this._removeWorker(workerInfo) + void this._removeWorker(workerInfo) if (workerInfo.isReady() && !this.workerFailsDuringBootstrap) { this._ensureMinimumWorkers() @@ -874,7 +874,7 @@ class ThreadPool { workerInfo.idleTimeout = setTimeout(() => { assert.strictEqual(workerInfo.taskInfos.size, 0) if (this.workers.size > this.options.minThreads) { - this._removeWorker(workerInfo) + void this._removeWorker(workerInfo) } }, this.options.idleTimeout).unref() } @@ -942,7 +942,7 @@ class ThreadPool { if (taskInfo.workerInfo !== null) { // Already running: We cancel the Worker this is running on. - this._removeWorker(taskInfo.workerInfo) + void this._removeWorker(taskInfo.workerInfo) this._ensureMinimumWorkers() } else { // Not yet running: Remove it from the queue. @@ -1063,7 +1063,7 @@ class ThreadPool { // @ts-ignore exitEvents.push(once(workerInfo.worker, 'exit')) // @ts-ignore - this._removeWorker(workerInfo) + void this._removeWorker(workerInfo) } await Promise.all(exitEvents) @@ -1090,7 +1090,7 @@ class ThreadPool { if (workerInfo.currentUsage() === 0) { // @ts-ignore exitEvents.push(once(workerInfo.worker, 'exit')) - this._removeWorker(workerInfo!) + void this._removeWorker(workerInfo!) } // Mark on-going workers for recycling. // Note that we don't need to wait for these ones to finish diff --git a/test/fixtures/nested-pool.mjs b/test/fixtures/nested-pool.mjs index 31f9dd6..3630dee 100644 --- a/test/fixtures/nested-pool.mjs +++ b/test/fixtures/nested-pool.mjs @@ -11,7 +11,7 @@ export default async function nestedPool() { }) await Promise.resolve() - pool.recycleWorkers() + void pool.recycleWorkers() } export function entrypoint() {} diff --git a/test/pool-destroy.test.ts b/test/pool-destroy.test.ts index d4ab01c..e4e672e 100644 --- a/test/pool-destroy.test.ts +++ b/test/pool-destroy.test.ts @@ -10,7 +10,9 @@ test('can destroy pool while tasks are running', async () => { filename: resolve(__dirname, 'fixtures/eval.js'), }) setImmediate(() => pool.destroy()) - expect(pool.run('while(1){}')).rejects.toThrow(/Terminating worker thread/) + await expect(pool.run('while(1){}')).rejects.toThrow( + /Terminating worker thread/ + ) }) test('destroy after initializing should work (#43)', async () => { @@ -19,8 +21,12 @@ test('destroy after initializing should work (#43)', async () => { isolateWorkers: true, }) - expect(pool.run({})).rejects.toThrow(/Terminating worker thread/) + const promise = expect(pool.run({})).rejects.toThrow( + /Terminating worker thread/ + ) + setImmediate(() => pool.destroy()) + await promise }) test('cleans up async resources', async () => { diff --git a/test/resource-limits.test.ts b/test/resource-limits.test.ts index d18e895..ca818c2 100644 --- a/test/resource-limits.test.ts +++ b/test/resource-limits.test.ts @@ -31,7 +31,7 @@ test('resourceLimits causes task to reject', async () => { expect(limits.maxOldGenerationSizeMb).toBe(4) expect(limits.maxYoungGenerationSizeMb).toBe(2) expect(limits.codeRangeSizeMb).toBe(4) - expect(worker.run(null)).rejects.toThrow( + await expect(worker.run(null)).rejects.toThrow( /Worker terminated due to reaching memory limit: JS heap out of memory/ ) }) diff --git a/test/simple.test.ts b/test/simple.test.ts index f2a5c78..17f6016 100644 --- a/test/simple.test.ts +++ b/test/simple.test.ts @@ -71,7 +71,7 @@ test('filename can be null when initially provided', async () => { test('filename must be provided while posting', async () => { const worker = new Tinypool() - expect(worker.run('doesn’t matter')).rejects.toThrow( + await expect(worker.run('doesn’t matter')).rejects.toThrow( /filename must be provided to run\(\) or in options object/ ) }) @@ -194,11 +194,11 @@ test('workerId should never be more than maxThreads=1', async () => { maxThreads: maxThreads, }) await pool.destroy() - expect(pool.run({})).resolves.toBeLessThanOrEqual(maxThreads) - expect(pool.run({})).resolves.toBeLessThanOrEqual(maxThreads) - expect(pool.run({})).resolves.toBeLessThanOrEqual(maxThreads) - expect(pool.run({})).resolves.toBeLessThanOrEqual(maxThreads) - expect(pool.run({})).resolves.toBeLessThanOrEqual(maxThreads) + await expect(pool.run({})).resolves.toBeLessThanOrEqual(maxThreads) + await expect(pool.run({})).resolves.toBeLessThanOrEqual(maxThreads) + await expect(pool.run({})).resolves.toBeLessThanOrEqual(maxThreads) + await expect(pool.run({})).resolves.toBeLessThanOrEqual(maxThreads) + await expect(pool.run({})).resolves.toBeLessThanOrEqual(maxThreads) await sleep(300) }) @@ -211,14 +211,14 @@ test('workerId should never be more than maxThreads', async () => { maxThreads: maxThreads, }) await pool.destroy() - expect(pool.run({})).resolves.toBeLessThanOrEqual(maxThreads) - expect(pool.run({})).resolves.toBeLessThanOrEqual(maxThreads) - expect(pool.run({})).resolves.toBeLessThanOrEqual(maxThreads) - expect(pool.run({})).resolves.toBeLessThanOrEqual(maxThreads) - expect(pool.run({})).resolves.toBeLessThanOrEqual(maxThreads) - expect(pool.run({})).resolves.toBeLessThanOrEqual(maxThreads) - expect(pool.run({})).resolves.toBeLessThanOrEqual(maxThreads) - expect(pool.run({})).resolves.toBeLessThanOrEqual(maxThreads) + await expect(pool.run({})).resolves.toBeLessThanOrEqual(maxThreads) + await expect(pool.run({})).resolves.toBeLessThanOrEqual(maxThreads) + await expect(pool.run({})).resolves.toBeLessThanOrEqual(maxThreads) + await expect(pool.run({})).resolves.toBeLessThanOrEqual(maxThreads) + await expect(pool.run({})).resolves.toBeLessThanOrEqual(maxThreads) + await expect(pool.run({})).resolves.toBeLessThanOrEqual(maxThreads) + await expect(pool.run({})).resolves.toBeLessThanOrEqual(maxThreads) + await expect(pool.run({})).resolves.toBeLessThanOrEqual(maxThreads) await sleep(300) }) diff --git a/test/task-queue.test.ts b/test/task-queue.test.ts index 1c2e8f1..54245ab 100644 --- a/test/task-queue.test.ts +++ b/test/task-queue.test.ts @@ -56,30 +56,44 @@ test('will reject items over task queue limit', async () => { maxThreads: 1, maxQueue: 2, }) + const promises: Promise[] = [] expect(pool.threads.length).toBe(0) expect(pool.queueSize).toBe(0) - expect(pool.run('while (true) {}')).rejects.toThrow( - /Terminating worker thread/ + promises.push( + expect(pool.run('while (true) {}')).rejects.toThrow( + /Terminating worker thread/ + ) ) + expect(pool.threads.length).toBe(1) expect(pool.queueSize).toBe(0) - expect(pool.run('while (true) {}')).rejects.toThrow( - /Terminating worker thread/ + promises.push( + expect(pool.run('while (true) {}')).rejects.toThrow( + /Terminating worker thread/ + ) ) expect(pool.threads.length).toBe(1) expect(pool.queueSize).toBe(1) - expect(pool.run('while (true) {}')).rejects.toThrow( - /Terminating worker thread/ + promises.push( + expect(pool.run('while (true) {}')).rejects.toThrow( + /Terminating worker thread/ + ) ) expect(pool.threads.length).toBe(1) expect(pool.queueSize).toBe(2) - expect(pool.run('while (true) {}')).rejects.toThrow(/Task queue is at limit/) + promises.push( + expect(pool.run('while (true) {}')).rejects.toThrow( + /Task queue is at limit/ + ) + ) + await pool.destroy() + await Promise.all(promises) }) test('will reject items when task queue is unavailable', async () => { @@ -89,20 +103,27 @@ test('will reject items when task queue is unavailable', async () => { maxThreads: 1, maxQueue: 0, }) + const promises: Promise[] = [] expect(pool.threads.length).toBe(0) expect(pool.queueSize).toBe(0) - expect(pool.run('while (true) {}')).rejects.toThrow( - /Terminating worker thread/ + promises.push( + expect(pool.run('while (true) {}')).rejects.toThrow( + /Terminating worker thread/ + ) ) expect(pool.threads.length).toBe(1) expect(pool.queueSize).toBe(0) - expect(pool.run('while (true) {}')).rejects.toThrow( - /No task queue available and all Workers are busy/ + promises.push( + expect(pool.run('while (true) {}')).rejects.toThrow( + /No task queue available and all Workers are busy/ + ) ) + await pool.destroy() + await Promise.all(promises) }) test('will reject items when task queue is unavailable (fixed thread count)', async () => { @@ -112,20 +133,27 @@ test('will reject items when task queue is unavailable (fixed thread count)', as maxThreads: 1, maxQueue: 0, }) + const promises: Promise[] = [] expect(pool.threads.length).toBe(1) expect(pool.queueSize).toBe(0) - expect(pool.run('while (true) {}')).rejects.toThrow( - /Terminating worker thread/ + promises.push( + expect(pool.run('while (true) {}')).rejects.toThrow( + /Terminating worker thread/ + ) ) expect(pool.threads.length).toBe(1) expect(pool.queueSize).toBe(0) - expect(pool.run('while (true) {}')).rejects.toThrow( - /No task queue available and all Workers are busy/ + promises.push( + expect(pool.run('while (true) {}')).rejects.toThrow( + /No task queue available and all Workers are busy/ + ) ) + await pool.destroy() + await Promise.all(promises) }) test('tasks can share a Worker if requested (both tests blocking)', async () => { @@ -136,23 +164,29 @@ test('tasks can share a Worker if requested (both tests blocking)', async () => maxQueue: 0, concurrentTasksPerWorker: 2, }) + const promises: Promise[] = [] expect(pool.threads.length).toBe(0) expect(pool.queueSize).toBe(0) - expect( - pool.run(new Int32Array(new SharedArrayBuffer(4))) - ).rejects.toBeTruthy() + promises.push( + expect( + pool.run(new Int32Array(new SharedArrayBuffer(4))) + ).rejects.toBeTruthy() + ) expect(pool.threads.length).toBe(1) expect(pool.queueSize).toBe(0) - expect( - pool.run(new Int32Array(new SharedArrayBuffer(4))) - ).rejects.toBeTruthy() + promises.push( + expect( + pool.run(new Int32Array(new SharedArrayBuffer(4))) + ).rejects.toBeTruthy() + ) expect(pool.threads.length).toBe(1) expect(pool.queueSize).toBe(0) await pool.destroy() + await Promise.all(promises) }) test('tasks can share a Worker if requested (both tests finish)', async () => { diff --git a/test/uncaught-exception-from-handler.test.ts b/test/uncaught-exception-from-handler.test.ts index 5946abd..4e47e1e 100644 --- a/test/uncaught-exception-from-handler.test.ts +++ b/test/uncaught-exception-from-handler.test.ts @@ -10,7 +10,7 @@ test('uncaught exception resets Worker', async () => { filename: resolve(__dirname, 'fixtures/eval.js'), }) - expect(pool.run('throw new Error("not_caught")')).rejects.toThrow( + await expect(pool.run('throw new Error("not_caught")')).rejects.toThrow( /not_caught/ ) })