Those are our results:
- CPU Intensive task with 100k operations submitted to each pool [BENCH-100000.MD](./versus-external-pools/BENCH-100000.MD).
-This benchmark ran on a MacBook Pro 2015, 2,2 GHz Intel Core i7 quad-core, 16 GB 1600 MHz DDR3.
+ This benchmark ran on a MacBook Pro 2015, 2,2 GHz Intel Core i7 quad-core, 16 GB 1600 MHz DDR3.
> :warning: **We would need funds to run our benchmarks more often and on Cloud VMs, please consider to sponsor this project**
module.exports = function (data) {
- if ( data.taskType === 'CPU_INTENSIVE' ) {
+ if (data.taskType === 'CPU_INTENSIVE') {
// CPU Intensive task
for (let i = 0; i <= 5000; i++) {
const o = {
{
"name": "poolifier",
- "version": "v2.0.0-beta.6",
+ "version": "2.0.0-beta.7",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
if (!this.isMain()) {
throw new Error('Cannot start a pool from a worker!')
}
+ this.checkNumberOfWorkers(this.numberOfWorkers)
this.checkFilePath(this.filePath)
this.setupHook()
}
}
+ private checkNumberOfWorkers (numberOfWorkers: number): void {
+ if (numberOfWorkers == null) {
+ throw new Error(
+ 'Cannot instantiate a pool without specifying the number of workers'
+ )
+ } else if (!Number.isSafeInteger(numberOfWorkers)) {
+ throw new Error(
+ 'Cannot instantiate a pool with a non integer number of workers'
+ )
+ } else if (numberOfWorkers < 0) {
+ throw new Error(
+ 'Cannot instantiate a pool with a negative number of workers'
+ )
+ } else if (!this.isDynamic() && numberOfWorkers === 0) {
+ throw new Error('Cannot instantiate a fixed pool with no worker')
+ }
+ }
+
/** @inheritdoc */
public isDynamic (): boolean {
return false
const expect = require('expect')
-const { FixedThreadPool } = require('../../../lib/index')
+const { FixedClusterPool, FixedThreadPool } = require('../../../lib/index')
const expectedError = new Error('Worker could not be found in tasks map')
class StubPoolWithTasksMapClear extends FixedThreadPool {
it('Simulate worker not found during increaseWorkersTask', () => {
const pool = new StubPoolWithTasksMapClear(
1,
- './tests/worker-files/cluster/testWorker.js',
+ './tests/worker-files/thread/testWorker.js',
{
errorHandler: e => console.error(e)
}
it('Simulate worker not found during decreaseWorkersTasks', () => {
const pool = new StubPoolWithTasksMapClear(
1,
- './tests/worker-files/cluster/testWorker.js',
+ './tests/worker-files/thread/testWorker.js',
{
errorHandler: e => console.error(e)
}
})
it('Simulate pool creation from a non main thread/process', () => {
- expect(() => {
- const pool = new StubPoolWithIsMainMethod(
- 1,
- './tests/worker-files/cluster/testWorker.js',
- {
- errorHandler: e => console.error(e)
- }
- )
- }).toThrowError()
+ expect(
+ () =>
+ new StubPoolWithIsMainMethod(
+ 1,
+ './tests/worker-files/thread/testWorker.js',
+ {
+ errorHandler: e => console.error(e)
+ }
+ )
+ ).toThrowError(new Error('Cannot start a pool from a worker!'))
})
it('Verify that filePath is checked', () => {
- expect(() => {
- const pool = new StubPoolWithIsMainMethod(1).toThrowError()
- })
- expect(() => {
- const pool = new StubPoolWithIsMainMethod(1, '').toThrowError()
- })
+ expect(() => new StubPoolWithIsMainMethod(1)).toThrowError(
+ new Error('Cannot start a pool from a worker!')
+ )
+ expect(() => new StubPoolWithIsMainMethod(1, '')).toThrowError(
+ new Error('Cannot start a pool from a worker!')
+ )
+ })
+
+ it('Verify that numberOfWorkers is checked', () => {
+ expect(() => new FixedThreadPool()).toThrowError(
+ new Error(
+ 'Cannot instantiate a pool without specifying the number of workers'
+ )
+ )
+ })
+
+ it('Verify that a negative number of workers is checked', () => {
+ expect(
+ () =>
+ new FixedClusterPool(-1, './tests/worker-files/cluster/testWorker.js')
+ ).toThrowError(
+ new Error('Cannot instantiate a pool with a negative number of workers')
+ )
+ })
+
+ it('Verify that a non integer number of workers is checked', () => {
+ expect(
+ () =>
+ new FixedThreadPool(0.25, './tests/worker-files/thread/testWorker.js')
+ ).toThrowError(
+ new Error(
+ 'Cannot instantiate a pool with a non integer number of workers'
+ )
+ )
})
})
expect(res).toBe(min)
})
+ it('Validation of inputs test', () => {
+ expect(() => new DynamicClusterPool(min)).toThrowError(
+ new Error('Please specify a file with a worker implementation')
+ )
+ })
+
it('Should work even without opts in input', async () => {
const pool1 = new DynamicClusterPool(
1,
// We need to clean up the resources after our test
await longRunningPool.destroy()
})
+
+ it('Verify that a pool with zero worker can be instantiated', async () => {
+ const pool = new DynamicClusterPool(
+ 0,
+ max,
+ './tests/worker-files/cluster/testWorker.js'
+ )
+ expect(pool).toBeInstanceOf(DynamicClusterPool)
+ // We need to clean up the resources after our test
+ await pool.destroy()
+ })
})
// We need to clean up the resources after our test
await pool1.destroy()
})
+
+ it('Verify that a pool with zero worker fails', async () => {
+ expect(
+ () =>
+ new FixedClusterPool(0, './tests/worker-files/cluster/testWorker.js')
+ ).toThrowError(new Error('Cannot instantiate a fixed pool with no worker'))
+ })
})
DynamicThreadPool,
FixedThreadPool
} = require('../../lib/index')
-const TestUtils = require('../test-utils')
describe('Selection strategies test suite', () => {
it('Verify that WorkerChoiceStrategies enumeration provides string values', () => {
expect(WorkerChoiceStrategies.LESS_RECENTLY_USED).toBe('LESS_RECENTLY_USED')
})
- it('Verify LESS_RECENTLY_USED is taken', async () => {
+ it('Verify LESS_RECENTLY_USED strategy is taken', async () => {
const max = 3
const pool = new FixedThreadPool(
max,
expect(closedThreads).toBe(min)
})
- it('Validations test', () => {
- expect(() => {
- const pool1 = new DynamicThreadPool()
- }).toThrowError(
+ it('Validation of inputs test', () => {
+ expect(() => new DynamicThreadPool(min)).toThrowError(
new Error('Please specify a file with a worker implementation')
)
})
// We need to clean up the resources after our test
await longRunningPool.destroy()
})
+
+ it('Verify that a pool with zero worker can be instantiated', async () => {
+ const pool = new DynamicThreadPool(
+ 0,
+ max,
+ './tests/worker-files/thread/testWorker.js'
+ )
+ expect(pool).toBeInstanceOf(DynamicThreadPool)
+ // We need to clean up the resources after our test
+ await pool.destroy()
+ })
})
// We need to clean up the resources after our test
await pool1.destroy()
})
+
+ it('Verify that a pool with zero worker fails', async () => {
+ expect(
+ () => new FixedThreadPool(0, './tests/worker-files/thread/testWorker.js')
+ ).toThrowError(new Error('Cannot instantiate a fixed pool with no worker'))
+ })
})
const expect = require('expect')
-const { ThreadWorker } = require('../../lib')
+const { ClusterWorker } = require('../../lib')
describe('Abstract worker test suite', () => {
it('Verify that fn function is mandatory', () => {
- expect(() => {
- const worker = new ThreadWorker()
- }).toThrowError()
+ expect(() => new ClusterWorker()).toThrowError(
+ new Error('fn parameter is mandatory')
+ )
})
})
const { ClusterWorker } = require('../../lib')
describe('Cluster worker test suite', () => {
- // Skipped because ClusterWorker would be in main instead of non-main worker
- it.skip('Verify worker has default maxInactiveTime', () => {
+ it('Verify worker has default maxInactiveTime', () => {
const worker = new ClusterWorker(() => {})
expect(worker.maxInactiveTime).toEqual(60_000)
})
const { ThreadWorker } = require('../../lib')
let numberOfMessagesPosted = 0
-const postMessage = function (message) {
+const postMessage = function () {
numberOfMessagesPosted++
- console.log(message)
}
class SpyWorker extends ThreadWorker {
getMainWorker () {