UNPKG

@jjavery/worker-pool

Version:

A worker pool for Node.js applications

184 lines 7.8 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); const chai_1 = require("chai"); const worker_pool_1 = __importStar(require("./worker-pool")); const worker_1 = require("./worker"); describe('WorkerPool', function () { it('creates a worker pool', async function () { const workerPool = new worker_pool_1.default({ start: false }); chai_1.assert.instanceOf(workerPool, worker_pool_1.default); chai_1.assert.isFalse(workerPool.isStarted); chai_1.assert.isFalse(workerPool.isStopping); chai_1.assert.isTrue(workerPool.isStopped); }); it('starts a worker pool', async function () { const workerPool = new worker_pool_1.default({ start: false }); await workerPool.start(); try { chai_1.assert.isTrue(workerPool.isStarted); chai_1.assert.isFalse(workerPool.isStopping); chai_1.assert.isFalse(workerPool.isStopped); } catch (err) { throw err; } finally { await workerPool.stop(); } }); it('stops a worker pool', async function () { const workerPool = new worker_pool_1.default(); const workerPoolStop = workerPool.stop(); try { chai_1.assert.isFalse(workerPool.isStarted); chai_1.assert.isTrue(workerPool.isStopping); chai_1.assert.isFalse(workerPool.isStopped); } catch (err) { throw err; } finally { await workerPoolStop; } chai_1.assert.isFalse(workerPool.isStarted); chai_1.assert.isFalse(workerPool.isStopping); chai_1.assert.isTrue(workerPool.isStopped); }); it('creates a worker pool with a minimum number of running workers', async function () { const workerPool = new worker_pool_1.default({ min: 2, start: false }); const runningCountBeforeStart = workerPool.getProcessCount(); await workerPool.start(); const runningCountAfterStart = workerPool.getProcessCount(); await workerPool.stop(); const runningCountAfterStop = workerPool.getProcessCount(); chai_1.assert.equal(runningCountBeforeStart, 0); chai_1.assert.equal(runningCountAfterStart, 2); chai_1.assert.equal(runningCountAfterStop, 0); }); it('calls a function exported by a worker module', async function () { const workerPool = new worker_pool_1.default(); const result = await workerPool.call('./test-worker', 'test', 'test'); await workerPool.stop(); chai_1.assert.equal(result, 'test'); }); it('proxies a function exported by a worker module', async function () { const workerPool = new worker_pool_1.default(); const testFunc = workerPool.proxy('./test-worker', 'test'); const result = await testFunc('test'); await workerPool.stop(); chai_1.assert.equal(result, 'test'); }); it('limits the maximum number of workers', async function () { const workerPool = new worker_pool_1.default({ max: 2, strategy: 'round-robin' }); await workerPool.call('./test-worker', 'test', 'test'); await workerPool.call('./test-worker', 'test', 'test'); await workerPool.call('./test-worker', 'test', 'test'); try { chai_1.assert.equal(workerPool.getProcessCount(), 2); } catch (err) { throw err; } finally { workerPool.stop(); } }); it('properly handles worker processes that exit unexpectedly', async function () { const workerPool = new worker_pool_1.default(); const exit = workerPool.proxy('./test-worker', 'exit'); try { await exit(); chai_1.assert.fail('Failed to throw'); } catch (err) { chai_1.assert.instanceOf(err, worker_1.UnexpectedExitError); } const testFunc = workerPool.proxy('./test-worker', 'test'); const result = await testFunc('test'); await workerPool.stop(); chai_1.assert.equal(result, 'test'); }); it('recycles a worker pool', async function () { const workerPool = new worker_pool_1.default(); const testFunc = workerPool.proxy('./test-worker', 'test'); testFunc('test') .then(() => { }) .catch((err) => { console.log(err); }); workerPool.recycle(); const result = await testFunc('test'); await workerPool.stop(); chai_1.assert.equal(result, 'test'); }); it('throws an error when calling a worker function after being stopped', async function () { const workerPool = new worker_pool_1.default(); await workerPool.stop(); const testFunc = workerPool.proxy('./test-worker', 'test'); try { await testFunc(); chai_1.assert.fail('Failed to throw'); } catch (err) { chai_1.assert.instanceOf(err, worker_pool_1.NotStartedError); } }); it('properly handles worker processes that throw errors', async function () { const workerPool = new worker_pool_1.default(); const throws = workerPool.proxy('./test-worker', 'throws'); try { await throws(); chai_1.assert.fail('Failed to throw'); } catch (err) { chai_1.assert.instanceOf(err, worker_1.WorkerError); } finally { await workerPool.stop(); } }); it('uses the "fewest" strategy to assign requests to workers', async function () { const workerPool = new worker_pool_1.default({ strategy: 'fewest' }); const result = await workerPool.call('./test-worker', 'test', 'test'); await workerPool.stop(); chai_1.assert.equal(result, 'test'); }); it('uses the "fill" strategy to assign requests to workers', async function () { const workerPool = new worker_pool_1.default({ strategy: 'fill' }); const result = await workerPool.call('./test-worker', 'test', 'test'); await workerPool.stop(); chai_1.assert.equal(result, 'test'); }); it('uses the "random" strategy to assign requests to workers', async function () { const workerPool = new worker_pool_1.default({ strategy: 'random' }); const result = await workerPool.call('./test-worker', 'test', 'test'); await workerPool.stop(); chai_1.assert.equal(result, 'test'); }); it('uses the "round-robin" strategy to assign requests to workers', async function () { const workerPool = new worker_pool_1.default({ strategy: 'round-robin' }); const result = await workerPool.call('./test-worker', 'test', 'test'); await workerPool.stop(); chai_1.assert.equal(result, 'test'); }); }); //# sourceMappingURL=worker-pool.test.js.map