export default {
'**/*.{ts,tsx,js,jsx,cjs,mjs}': [
- 'biome format --write',
- 'eslint --cache --fix',
+ // 'biome format --write',
+ // 'eslint --cache --fix',
+ 'eslint --cache',
],
'**/*.json': ['biome format --write'],
'**/*.{md,yml,yaml}': ['prettier --cache --write'],
js.configs.recommended,
...nodePlugin.configs['flat/mixed-esm-and-cjs'],
jsdoc.configs['flat/recommended-typescript'],
- ...tseslint.config(...tseslint.configs.strict, ...tseslint.configs.stylistic),
+ ...tseslint.config(
+ ...tseslint.configs.strictTypeChecked,
+ ...tseslint.configs.stylisticTypeChecked
+ ),
...neostandard({
ts: true,
globals: {
...globals.mocha,
},
}),
- // ...tseslint.config(
- // ...tseslint.configs.strictTypeChecked,
- // ...tseslint.configs.stylisticTypeChecked,
- // {
- // languageOptions: {
- // parserOptions: {
- // project: true,
- // tsconfigRootDir: import.meta.dirname,
- // },
- // },
- // }
- // ),
+ {
+ languageOptions: {
+ parserOptions: {
+ project: true,
+ tsconfigRootDir: import.meta.dirname,
+ },
+ },
+ },
{
plugins: {
'simple-import-sort': simpleImportSort,
},
},
{
- files: ['examples/**/*.ts'],
- rules: {
- 'no-undef': 'off',
- },
+ files: ['**/*.js', '**/*.mjs', '**/*.cjs'],
+ ...tseslint.configs.disableTypeChecked,
},
+ // examples specific configuration
+ // {
+ // files: ['examples/**/*.ts'],
+ // rules: {
+ // 'no-undef': 'off',
+ // },
+ // },
{
files: ['examples/**/*.js', 'examples/**/*.cjs'],
rules: {
'@typescript-eslint/no-require-imports': 'off',
},
},
+ // benchmarks specific configuration
{
files: ['benchmarks/**/*.cjs'],
rules: {
'@typescript-eslint/no-require-imports': 'off',
},
},
+ // tests specific configuration
{
files: ['tests/**/*.js', 'tests/**/*.mjs', 'tests/**/*.cjs'],
rules: {
const responses = await Promise.all(httpClientPoolPromises)
const elapsedTime = performance.now() - now
console.info(
- `Received in ${elapsedTime.toFixed(2)}ms an array with ${
- responses.length
- } responses from ${parallelism} parallel requests made with HTTP client pool task function ${workerFunction} on ${requestUrl}:\n`,
+ `Received in ${elapsedTime.toFixed(
+ 2
+ )}ms an array with ${responses.length.toString()} responses from ${parallelism.toString()} parallel requests made with HTTP client pool task function ${workerFunction} on ${requestUrl}:\n`,
responses
)
} catch (error) {
...workerData?.axiosRequestConfig,
})
return {
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
text: response.data,
}
},
.then(response => {
if (response.status) {
console.info(
- `Express is listening in cluster worker on port ${response.port}`
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
+ `Express is listening in cluster worker on port ${response.port?.toString()}`
)
}
return undefined
ExpressWorker.server = application.listen(port, () => {
listenerPort = (ExpressWorker.server.address() as AddressInfo).port
console.info(
- `⚡️[express server]: Express server is started in cluster worker at http://localhost:${listenerPort}/`
+ `⚡️[express server]: Express server is started in cluster worker at http://localhost:${listenerPort.toString()}/`
)
})
return {
application.all('/api/echo', (req: Request, res: Response) => {
ExpressWorker.requestHandlerPool
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
.execute({ data: req.body }, 'echo')
.then(response => {
return res.send(response.data).end()
ExpressWorker.server = application.listen(port, () => {
listenerPort = (ExpressWorker.server.address() as AddressInfo).port
console.info(
- `⚡️[express server]: Express server is started in cluster worker at http://localhost:${listenerPort}/`
+ `⚡️[express server]: Express server is started in cluster worker at http://localhost:${listenerPort.toString()}/`
)
})
return {
.then(response => {
if (response.status) {
console.info(
- `Express is listening in cluster worker on port ${response.port}`
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
+ `Express is listening in cluster worker on port ${response.port?.toString()}`
)
}
return undefined
expressApp.all('/api/echo', (req: Request, res: Response) => {
requestHandlerPool
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
.execute({ body: req.body }, 'echo')
.then(response => {
return res.send(response.body).end()
try {
expressApp.listen(port, () => {
console.info(
- `⚡️[express server]: Express server is started at http://localhost:${port}/`
+ `⚡️[express server]: Express server is started at http://localhost:${port.toString()}/`
)
})
} catch (err) {
.then(response => {
if (response.status) {
console.info(
- `Fastify is listening in cluster worker on port ${response.port}`
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
+ `Fastify is listening in cluster worker on port ${response.port?.toString()}`
)
}
return undefined
.then(response => {
if (response.status) {
console.info(
- `Fastify is listening in cluster worker on port ${response.port}`
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
+ `Fastify is listening in cluster worker on port ${response.port?.toString()}`
)
}
return undefined
await dynamicPool.execute()
+// eslint-disable-next-line @typescript-eslint/no-misused-promises
setTimeout(async () => {
await fixedPool.destroy()
await dynamicPool.destroy()
await Promise.all(smtpClientPoolPromises)
const elapsedTime = performance.now() - now
console.info(
- `Send in parallel in ${elapsedTime.toFixed(2)}ms ${
- tos.length
- } mails with SMTP client pool`
+ `Send in parallel in ${elapsedTime.toFixed(
+ 2
+ )}ms ${tos.length.toString()} mails with SMTP client pool`
)
} catch (error) {
console.error(error)
.then(response => {
if (response.status) {
console.info(
- `WebSocket server is listening in cluster worker on port ${response.port}`
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
+ `WebSocket server is listening in cluster worker on port ${response.port?.toString()}`
)
}
return undefined
WebSocketServerWorker.wss = new WebSocketServer({ port }, () => {
console.info(
- `⚡️[ws server]: WebSocket server is started in cluster worker at ws://localhost:${port}/`
+ `⚡️[ws server]: WebSocket server is started in cluster worker at ws://localhost:${port.toString()}/`
)
})
ws.on('error', console.error)
ws.on('message', (message: RawData) => {
const { type, data } = JSON.parse(
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
message.toString()
) as MessagePayload<DataPayload>
switch (type) {
number: WebSocketServerWorker.factorial(data.number!),
},
},
- (_, v) => (typeof v === 'bigint' ? v.toString() : v)
+ (_, v: unknown) => (typeof v === 'bigint' ? v.toString() : v)
)
)
break
.then(response => {
if (response.status) {
console.info(
- `WebSocket server is listening in cluster worker on port ${response.port}`
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
+ `WebSocket server is listening in cluster worker on port ${response.port?.toString()}`
)
}
return undefined
WebSocketServerWorker.wss = new WebSocketServer({ port }, () => {
console.info(
- `⚡️[ws server]: WebSocket server is started in cluster worker at ws://localhost:${port}/`
+ `⚡️[ws server]: WebSocket server is started in cluster worker at ws://localhost:${port.toString()}/`
)
})
ws.on('error', console.error)
ws.on('message', (message: RawData) => {
const { type, data } = JSON.parse(
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
message.toString()
) as MessagePayload<DataPayload>
switch (type) {
type: MessageType.factorial,
data: response.data,
},
- (_, v) => (typeof v === 'bigint' ? v.toString() : v)
+ (_, v: unknown) =>
+ typeof v === 'bigint' ? v.toString() : v
)
)
return undefined
const port = 8080
const wss = new WebSocketServer({ port }, () => {
console.info(
- `⚡️[ws server]: WebSocket server is started at ws://localhost:${port}/`
+ `⚡️[ws server]: WebSocket server is started at ws://localhost:${port.toString()}/`
)
})
ws.on('error', console.error)
ws.on('message', (message: RawData) => {
const { type, data } = JSON.parse(
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
message.toString()
) as MessagePayload<DataPayload>
switch (type) {
type: MessageType.factorial,
data: response.data,
},
- (_, v) => (typeof v === 'bigint' ? v.toString() : v)
+ (_, v: unknown) => (typeof v === 'bigint' ? v.toString() : v)
)
)
return undefined
private checkSize (size: number): void {
if (!Number.isSafeInteger(size)) {
throw new TypeError(
- `Invalid circular buffer size: '${size}' is not an integer`
+ `Invalid circular buffer size: '${size.toString()}' is not an integer`
)
}
if (size < 0) {
- throw new RangeError(`Invalid circular buffer size: ${size} < 0`)
+ throw new RangeError(
+ `Invalid circular buffer size: ${size.toString()} < 0`
+ )
}
}
}
private checkSize (size: number): void {
if (!Number.isSafeInteger(size)) {
throw new TypeError(
- `Invalid fixed priority queue size: '${size}' is not an integer`
+ `Invalid fixed priority queue size: '${size.toString()}' is not an integer`
)
}
if (size < 0) {
- throw new RangeError(`Invalid fixed priority queue size: ${size} < 0`)
+ throw new RangeError(
+ `Invalid fixed priority queue size: ${size.toString()} < 0`
+ )
}
}
}
throw new Error('Worker message received without worker id')
} else if (this.getWorkerNodeKeyByWorkerId(message.workerId) === -1) {
throw new Error(
- `Worker message received from unknown worker '${message.workerId}'`
+ `Worker message received from unknown worker '${message.workerId.toString()}'`
)
}
}
} else {
reject(
new Error(
- `Task function operation '${message.taskFunctionOperation}' failed on worker ${message.workerId} with error: '${message.workerError?.message}'`
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
+ `Task function operation '${message.taskFunctionOperation?.toString()}' failed on worker ${message.workerId?.toString()} with error: '${
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
+ message.workerError?.message
+ }'`
)
)
}
new Error(
`Task function operation '${
message.taskFunctionOperation as string
- }' failed on worker ${errorResponse?.workerId} with error: '${
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
+ }' failed on worker ${errorResponse?.workerId?.toString()} with error: '${
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
errorResponse?.workerError?.message
}'`
)
private async sendKillMessageToWorker (workerNodeKey: number): Promise<void> {
await new Promise<void>((resolve, reject) => {
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (this.workerNodes[workerNodeKey] == null) {
resolve()
return
} else if (message.kill === 'failure') {
reject(
new Error(
- `Kill message handling failed on worker ${message.workerId}`
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
+ `Kill message handling failed on worker ${message.workerId?.toString()}`
)
)
}
workerNodeKey: number,
task: Task<Data>
): void {
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (this.workerNodes[workerNodeKey]?.usage != null) {
const workerUsage = this.workerNodes[workerNodeKey].usage
++workerUsage.tasks.executing
message: MessageValue<Response>
): void {
let needWorkerChoiceStrategiesUpdate = false
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (this.workerNodes[workerNodeKey]?.usage != null) {
const workerUsage = this.workerNodes[workerNodeKey].usage
updateTaskStatisticsWorkerUsage(workerUsage, message)
) {
this.redistributeQueuedTasks(this.workerNodes.indexOf(workerNode))
}
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
workerNode?.terminate().catch((error: unknown) => {
this.emitter?.emit(PoolEvents.error, error)
})
taskName: string
): void {
const workerNode = this.workerNodes[workerNodeKey]
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (workerNode?.usage != null) {
++workerNode.usage.tasks.stolen
}
previousTaskName?: string
): void {
const workerNode = this.workerNodes[workerNodeKey]
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (workerNode?.usage != null) {
++workerNode.usage.tasks.sequentiallyStolen
}
taskName: string
): void {
const workerNode = this.workerNodes[workerNodeKey]
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (workerNode?.usage != null) {
workerNode.usage.tasks.sequentiallyStolen = 0
}
const workerInfo = this.getWorkerInfo(workerNodeKey)
if (workerInfo == null) {
throw new Error(
- `Worker node with key '${workerNodeKey}' not found in pool`
+ `Worker node with key '${workerNodeKey.toString()}' not found in pool`
)
}
if (
const workerInfo = this.getWorkerInfo(workerNodeKey)
if (workerInfo == null) {
throw new Error(
- `Worker node with key '${workerNodeKey}' not found in pool`
+ `Worker node with key '${workerNodeKey.toString()}' not found in pool`
)
}
workerInfo.stealing = true
private handleWorkerReadyResponse (message: MessageValue<Response>): void {
const { workerId, ready, taskFunctionsProperties } = message
if (ready == null || !ready) {
- throw new Error(`Worker ${workerId} failed to initialize`)
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
+ throw new Error(`Worker ${workerId?.toString()} failed to initialize`)
}
const workerNodeKey = this.getWorkerNodeKeyByWorkerId(workerId)
const workerNode = this.workerNodes[workerNodeKey]
this.afterTaskExecutionHook(workerNodeKey, message)
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
this.promiseResponseMap.delete(taskId!)
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
workerNode?.emit('taskFinished', taskId)
if (
this.opts.enableTasksQueue === true &&
!this.destroying &&
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
workerNode != null
) {
const workerNodeTasksUsage = workerNode.usage.tasks
const getDefaultWorkerWeight = (): number => {
const currentCpus = cpus()
let estCpuSpeed: number | undefined
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (currentCpus.every(cpu => cpu.speed == null || cpu.speed === 0)) {
estCpuSpeed = estimatedCpuSpeed()
}
let cpusCycleTimeWeight = 0
for (const cpu of currentCpus) {
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (cpu.speed == null || cpu.speed === 0) {
cpu.speed =
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
currentCpus.find(cpu => cpu.speed != null && cpu.speed !== 0)?.speed ??
estCpuSpeed ??
2000
))(pool, opts)
default:
throw new Error(
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
`Worker choice strategy '${workerChoiceStrategy}' is not valid`
)
}
} while (workerNodeKey == null && retriesCount < this.retries)
if (workerNodeKey == null) {
throw new Error(
- `Worker node key chosen is null or undefined after ${retriesCount} retries`
+ `Worker node key chosen is null or undefined after ${retriesCount.toString()} retries`
)
}
return workerNodeKey
export const checkValidPriority = (priority: number | undefined): void => {
if (priority != null && !Number.isSafeInteger(priority)) {
- throw new TypeError(`Invalid property 'priority': '${priority}'`)
+ throw new TypeError(`Invalid property 'priority': '${priority.toString()}'`)
}
if (
priority != null &&
tasksQueueOptions.concurrency <= 0
) {
throw new RangeError(
- `Invalid worker node tasks concurrency: ${tasksQueueOptions.concurrency} is a negative integer or zero`
+ `Invalid worker node tasks concurrency: ${tasksQueueOptions.concurrency.toString()} is a negative integer or zero`
)
}
if (
}
if (tasksQueueOptions?.size != null && tasksQueueOptions.size <= 0) {
throw new RangeError(
- `Invalid worker node tasks queue size: ${tasksQueueOptions.size} is a negative integer or zero`
+ `Invalid worker node tasks queue size: ${tasksQueueOptions.size.toString()} is a negative integer or zero`
)
}
}
}
}
if (env.NODE_ENV === 'test') {
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
exports.updateMeasurementStatistics = updateMeasurementStatistics
}
): void => {
const workerTaskStatistics = workerUsage.tasks
if (
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
workerTaskStatistics.executing != null &&
workerTaskStatistics.executing > 0
) {
case WorkerTypes.cluster:
return cluster.fork(opts.env) as unknown as Worker
default:
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
throw new Error(`Unknown worker type '${type}'`)
}
}
) {
if (!Number.isSafeInteger(bucketSize)) {
throw new TypeError(
- `Invalid bucket size: '${bucketSize}' is not an integer`
+ `Invalid bucket size: '${bucketSize.toString()}' is not an integer`
)
}
if (bucketSize < 0) {
- throw new RangeError(`Invalid bucket size: ${bucketSize} < 0`)
+ throw new RangeError(`Invalid bucket size: ${bucketSize.toString()} < 0`)
}
this.bucketSize = bucketSize
this.head = this.tail = new FixedPriorityQueue(
): ((...args: A) => R) => {
let result: R
return (...args: A) => {
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (fn != null) {
result = fn.apply<C, A, R>(context, args)
;(fn as unknown as undefined) = (context as unknown as undefined) =
switch (taskFunctionOperation) {
case 'add':
response = this.addTaskFunction(taskFunctionProperties.name, {
- // eslint-disable-next-line no-new-func
+ // eslint-disable-next-line @typescript-eslint/no-implied-eval, no-new-func
taskFunction: new Function(
- `return ${taskFunction}`
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ `return ${taskFunction!}`
)() as TaskFunction<Data, Response>,
...(taskFunctionProperties.priority != null && {
priority: taskFunctionProperties.priority,
})
} else {
try {
- this.opts.killHandler?.()
+ ;(this.opts.killHandler as (() => void) | undefined)?.()
this.sendToMainWorker({ kill: 'success' })
} catch {
this.sendToMainWorker({ kill: 'failure' })
throw new Error('Message worker id is not set')
} else if (message.workerId !== this.id) {
throw new Error(
- `Message worker id ${message.workerId} does not match the worker id ${this.id}`
+ `Message worker id ${message.workerId.toString()} does not match the worker id ${this.id.toString()}`
)
}
}
workerError: {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
name: name!,
- message: `Task function '${name}' not found`,
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ message: `Task function '${name!}' not found`,
data,
},
taskId,
workerError: {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
name: name!,
- message: this.handleError(error as Error | string),
+ message: this.handleError(error),
data,
},
taskId,
}
if (typeof fnObj.taskFunction !== 'function') {
throw new TypeError(
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
`taskFunction object 'taskFunction' property '${fnObj.taskFunction}' is not a function`
)
}