Signed-off-by: Jérôme Benoit <jerome.benoit@piment-noir.org>
29 files changed:
project: './tsconfig.json'
},
extends: [
project: './tsconfig.json'
},
extends: [
- 'plugin:@typescript-eslint/recommended',
- 'plugin:@typescript-eslint/recommended-requiring-type-checking',
+ 'plugin:@typescript-eslint/strict-type-checked',
+ 'plugin:@typescript-eslint/stylistic-type-checked',
'plugin:import/typescript',
'standard-with-typescript'
],
'plugin:import/typescript',
'standard-with-typescript'
],
.then(response => {
if (response.status) {
console.info(
.then(response => {
if (response.status) {
console.info(
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
- `Express is listening in cluster worker on port ${response?.port}`
+ `Express is listening in cluster worker on port ${response.port}`
ExpressWorker.server = application.listen(port, () => {
console.info(
ExpressWorker.server = application.listen(port, () => {
console.info(
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
`⚡️[express server]: Express server is started in cluster worker at http://localhost:${port}/`
)
})
return {
status: true,
`⚡️[express server]: Express server is started in cluster worker at http://localhost:${port}/`
)
})
return {
status: true,
- port: (ExpressWorker.server.address() as AddressInfo)?.port ?? port
+ port: (ExpressWorker.server.address() as AddressInfo).port
ExpressWorker.server = application.listen(port, () => {
console.info(
ExpressWorker.server = application.listen(port, () => {
console.info(
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
`⚡️[express server]: Express server is started in cluster worker at http://localhost:${port}/`
)
})
return {
status: true,
`⚡️[express server]: Express server is started in cluster worker at http://localhost:${port}/`
)
})
return {
status: true,
- port: (ExpressWorker.server.address() as AddressInfo)?.port ?? port
+ port: (ExpressWorker.server.address() as AddressInfo).port
.then(response => {
if (response.status) {
console.info(
.then(response => {
if (response.status) {
console.info(
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
- `Express is listening in cluster worker on port ${response?.port}`
+ `Express is listening in cluster worker on port ${response.port}`
.then(response => {
if (response.status) {
console.info(
.then(response => {
if (response.status) {
console.info(
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
`Fastify is listening in cluster worker on port ${response.port}`
)
}
`Fastify is listening in cluster worker on port ${response.port}`
)
}
await FastifyWorker.fastify.listen({ port })
return {
status: true,
await FastifyWorker.fastify.listen({ port })
return {
status: true,
- port: (FastifyWorker.fastify.server.address() as AddressInfo)?.port
+ port: (FastifyWorker.fastify.server.address() as AddressInfo).port
await FastifyWorker.fastify.listen({ port })
return {
status: true,
await FastifyWorker.fastify.listen({ port })
return {
status: true,
- port: (FastifyWorker.fastify.server.address() as AddressInfo)?.port
+ port: (FastifyWorker.fastify.server.address() as AddressInfo).port
.then(response => {
if (response.status) {
console.info(
.then(response => {
if (response.status) {
console.info(
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
`Fastify is listening in cluster worker on port ${response.port}`
)
}
`Fastify is listening in cluster worker on port ${response.port}`
)
}
.then(response => {
if (response.status) {
console.info(
.then(response => {
if (response.status) {
console.info(
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
`WebSocket server is listening in cluster worker on port ${response.port}`
)
}
`WebSocket server is listening in cluster worker on port ${response.port}`
)
}
.then(response => {
if (response.status) {
console.info(
.then(response => {
if (response.status) {
console.info(
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
`WebSocket server is listening in cluster worker on port ${response.port}`
)
}
`WebSocket server is listening in cluster worker on port ${response.port}`
)
}
return
}
const tail = this.tail
return
}
const tail = this.tail
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- this.tail = this.tail!.prev
+ this.tail = this.tail?.prev
if (this.tail == null) {
delete this.head
} else {
if (this.tail == null) {
delete this.head
} else {
delete this.head.prev
}
--this.size
delete this.head.prev
}
--this.size
value: node.data,
done: false
}
value: node.data,
done: false
}
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- node = node.next!
value: node.data,
done: false
}
value: node.data,
done: false
}
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- node = node.prev!
/**
* Worker choice strategy context referencing a worker choice algorithm implementation.
*/
/**
* Worker choice strategy context referencing a worker choice algorithm implementation.
*/
- protected workerChoiceStrategyContext: WorkerChoiceStrategyContext<
+ protected workerChoiceStrategyContext?: WorkerChoiceStrategyContext<
- private checkMinimumNumberOfWorkers (minimumNumberOfWorkers: number): void {
+ private checkMinimumNumberOfWorkers (
+ minimumNumberOfWorkers: number | undefined
+ ): void {
if (minimumNumberOfWorkers == null) {
throw new Error(
'Cannot instantiate a pool without specifying the number of workers'
if (minimumNumberOfWorkers == null) {
throw new Error(
'Cannot instantiate a pool without specifying the number of workers'
private checkPoolOptions (opts: PoolOptions<Worker>): void {
if (isPlainObject(opts)) {
this.opts.startWorkers = opts.startWorkers ?? true
private checkPoolOptions (opts: PoolOptions<Worker>): void {
if (isPlainObject(opts)) {
this.opts.startWorkers = opts.startWorkers ?? true
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- checkValidWorkerChoiceStrategy(opts.workerChoiceStrategy!)
+ checkValidWorkerChoiceStrategy(opts.workerChoiceStrategy)
this.opts.workerChoiceStrategy =
opts.workerChoiceStrategy ?? WorkerChoiceStrategies.ROUND_ROBIN
this.checkValidWorkerChoiceStrategyOptions(
this.opts.workerChoiceStrategy =
opts.workerChoiceStrategy ?? WorkerChoiceStrategies.ROUND_ROBIN
this.checkValidWorkerChoiceStrategyOptions(
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- opts.workerChoiceStrategyOptions!
+ opts.workerChoiceStrategyOptions
)
if (opts.workerChoiceStrategyOptions != null) {
this.opts.workerChoiceStrategyOptions = opts.workerChoiceStrategyOptions
)
if (opts.workerChoiceStrategyOptions != null) {
this.opts.workerChoiceStrategyOptions = opts.workerChoiceStrategyOptions
this.opts.enableEvents = opts.enableEvents ?? true
this.opts.enableTasksQueue = opts.enableTasksQueue ?? false
if (this.opts.enableTasksQueue) {
this.opts.enableEvents = opts.enableEvents ?? true
this.opts.enableTasksQueue = opts.enableTasksQueue ?? false
if (this.opts.enableTasksQueue) {
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- checkValidTasksQueueOptions(opts.tasksQueueOptions!)
+ checkValidTasksQueueOptions(opts.tasksQueueOptions)
this.opts.tasksQueueOptions = this.buildTasksQueueOptions(
this.opts.tasksQueueOptions = this.buildTasksQueueOptions(
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- opts.tasksQueueOptions!
}
private checkValidWorkerChoiceStrategyOptions (
}
private checkValidWorkerChoiceStrategyOptions (
- workerChoiceStrategyOptions: WorkerChoiceStrategyOptions
+ workerChoiceStrategyOptions: WorkerChoiceStrategyOptions | undefined
): void {
if (
workerChoiceStrategyOptions != null &&
): void {
if (
workerChoiceStrategyOptions != null &&
minSize: this.minimumNumberOfWorkers,
maxSize: this.maximumNumberOfWorkers ?? this.minimumNumberOfWorkers,
...(this.workerChoiceStrategyContext?.getTaskStatisticsRequirements()
minSize: this.minimumNumberOfWorkers,
maxSize: this.maximumNumberOfWorkers ?? this.minimumNumberOfWorkers,
...(this.workerChoiceStrategyContext?.getTaskStatisticsRequirements()
- .runTime.aggregate &&
- this.workerChoiceStrategyContext?.getTaskStatisticsRequirements()
- .waitTime.aggregate && { utilization: round(this.utilization) }),
+ ?.runTime.aggregate === true &&
+ this.workerChoiceStrategyContext.getTaskStatisticsRequirements()
+ .waitTime.aggregate && {
+ utilization: round(this.utilization)
+ }),
workerNodes: this.workerNodes.length,
idleWorkerNodes: this.workerNodes.reduce(
(accumulator, workerNode) =>
workerNodes: this.workerNodes.length,
idleWorkerNodes: this.workerNodes.reduce(
(accumulator, workerNode) =>
...(this.opts.enableTasksQueue === true && {
maxQueuedTasks: this.workerNodes.reduce(
(accumulator, workerNode) =>
...(this.opts.enableTasksQueue === true && {
maxQueuedTasks: this.workerNodes.reduce(
(accumulator, workerNode) =>
- accumulator + (workerNode.usage.tasks?.maxQueued ?? 0),
+ accumulator + (workerNode.usage.tasks.maxQueued ?? 0),
0
),
...(this.workerChoiceStrategyContext?.getTaskStatisticsRequirements()
0
),
...(this.workerChoiceStrategyContext?.getTaskStatisticsRequirements()
- .runTime.aggregate && {
+ ?.runTime.aggregate === true && {
runTime: {
minimum: round(
min(
...this.workerNodes.map(
runTime: {
minimum: round(
min(
...this.workerNodes.map(
- workerNode => workerNode.usage.runTime?.minimum ?? Infinity
+ workerNode => workerNode.usage.runTime.minimum ?? Infinity
)
)
),
maximum: round(
max(
...this.workerNodes.map(
)
)
),
maximum: round(
max(
...this.workerNodes.map(
- workerNode => workerNode.usage.runTime?.maximum ?? -Infinity
+ workerNode => workerNode.usage.runTime.maximum ?? -Infinity
- ...(this.workerChoiceStrategyContext?.getTaskStatisticsRequirements()
+ ...(this.workerChoiceStrategyContext.getTaskStatisticsRequirements()
.runTime.average && {
average: round(
average(
.runTime.average && {
average: round(
average(
- ...(this.workerChoiceStrategyContext?.getTaskStatisticsRequirements()
+ ...(this.workerChoiceStrategyContext.getTaskStatisticsRequirements()
.runTime.median && {
median: round(
median(
.runTime.median && {
median: round(
median(
}
}),
...(this.workerChoiceStrategyContext?.getTaskStatisticsRequirements()
}
}),
...(this.workerChoiceStrategyContext?.getTaskStatisticsRequirements()
- .waitTime.aggregate && {
+ ?.waitTime.aggregate === true && {
waitTime: {
minimum: round(
min(
...this.workerNodes.map(
waitTime: {
minimum: round(
min(
...this.workerNodes.map(
- workerNode => workerNode.usage.waitTime?.minimum ?? Infinity
+ workerNode => workerNode.usage.waitTime.minimum ?? Infinity
)
)
),
maximum: round(
max(
...this.workerNodes.map(
)
)
),
maximum: round(
max(
...this.workerNodes.map(
- workerNode => workerNode.usage.waitTime?.maximum ?? -Infinity
+ workerNode => workerNode.usage.waitTime.maximum ?? -Infinity
- ...(this.workerChoiceStrategyContext?.getTaskStatisticsRequirements()
+ ...(this.workerChoiceStrategyContext.getTaskStatisticsRequirements()
.waitTime.average && {
average: round(
average(
.waitTime.average && {
average: round(
average(
- ...(this.workerChoiceStrategyContext?.getTaskStatisticsRequirements()
+ ...(this.workerChoiceStrategyContext.getTaskStatisticsRequirements()
.waitTime.median && {
median: round(
median(
.waitTime.median && {
median: round(
median(
(this.maximumNumberOfWorkers ?? this.minimumNumberOfWorkers)
const totalTasksRunTime = this.workerNodes.reduce(
(accumulator, workerNode) =>
(this.maximumNumberOfWorkers ?? this.minimumNumberOfWorkers)
const totalTasksRunTime = this.workerNodes.reduce(
(accumulator, workerNode) =>
- accumulator + (workerNode.usage.runTime?.aggregate ?? 0),
+ accumulator + (workerNode.usage.runTime.aggregate ?? 0),
0
)
const totalTasksWaitTime = this.workerNodes.reduce(
(accumulator, workerNode) =>
0
)
const totalTasksWaitTime = this.workerNodes.reduce(
(accumulator, workerNode) =>
- accumulator + (workerNode.usage.waitTime?.aggregate ?? 0),
+ accumulator + (workerNode.usage.waitTime.aggregate ?? 0),
0
)
return (totalTasksRunTime + totalTasksWaitTime) / poolTimeCapacity
0
)
return (totalTasksRunTime + totalTasksWaitTime) / poolTimeCapacity
): void {
checkValidWorkerChoiceStrategy(workerChoiceStrategy)
this.opts.workerChoiceStrategy = workerChoiceStrategy
): void {
checkValidWorkerChoiceStrategy(workerChoiceStrategy)
this.opts.workerChoiceStrategy = workerChoiceStrategy
- this.workerChoiceStrategyContext.setWorkerChoiceStrategy(
+ this.workerChoiceStrategyContext?.setWorkerChoiceStrategy(
this.opts.workerChoiceStrategy
)
if (workerChoiceStrategyOptions != null) {
this.opts.workerChoiceStrategy
)
if (workerChoiceStrategyOptions != null) {
/** @inheritDoc */
public setWorkerChoiceStrategyOptions (
/** @inheritDoc */
public setWorkerChoiceStrategyOptions (
- workerChoiceStrategyOptions: WorkerChoiceStrategyOptions
+ workerChoiceStrategyOptions: WorkerChoiceStrategyOptions | undefined
): void {
this.checkValidWorkerChoiceStrategyOptions(workerChoiceStrategyOptions)
if (workerChoiceStrategyOptions != null) {
this.opts.workerChoiceStrategyOptions = workerChoiceStrategyOptions
}
): void {
this.checkValidWorkerChoiceStrategyOptions(workerChoiceStrategyOptions)
if (workerChoiceStrategyOptions != null) {
this.opts.workerChoiceStrategyOptions = workerChoiceStrategyOptions
}
- this.workerChoiceStrategyContext.setOptions(
+ this.workerChoiceStrategyContext?.setOptions(
this.opts.workerChoiceStrategyOptions
)
}
this.opts.workerChoiceStrategyOptions
)
}
this.flushTasksQueues()
}
this.opts.enableTasksQueue = enable
this.flushTasksQueues()
}
this.opts.enableTasksQueue = enable
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- this.setTasksQueueOptions(tasksQueueOptions!)
+ this.setTasksQueueOptions(tasksQueueOptions)
- public setTasksQueueOptions (tasksQueueOptions: TasksQueueOptions): void {
+ public setTasksQueueOptions (
+ tasksQueueOptions: TasksQueueOptions | undefined
+ ): void {
if (this.opts.enableTasksQueue === true) {
checkValidTasksQueueOptions(tasksQueueOptions)
this.opts.tasksQueueOptions =
if (this.opts.enableTasksQueue === true) {
checkValidTasksQueueOptions(tasksQueueOptions)
this.opts.tasksQueueOptions =
}
private buildTasksQueueOptions (
}
private buildTasksQueueOptions (
- tasksQueueOptions: TasksQueueOptions
+ tasksQueueOptions: TasksQueueOptions | undefined
): TasksQueueOptions {
return {
...getDefaultTasksQueueOptions(
): TasksQueueOptions {
return {
...getDefaultTasksQueueOptions(
message: MessageValue<Response>
): void => {
this.checkMessageWorkerId(message)
message: MessageValue<Response>
): void => {
this.checkMessageWorkerId(message)
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- const workerId = this.getWorkerInfo(workerNodeKey).id!
+ const workerId = this.getWorkerInfo(workerNodeKey).id
if (
message.taskFunctionOperationStatus != null &&
message.workerId === workerId
) {
if (message.taskFunctionOperationStatus) {
resolve(true)
if (
message.taskFunctionOperationStatus != null &&
message.workerId === workerId
) {
if (message.taskFunctionOperationStatus) {
resolve(true)
- } else if (!message.taskFunctionOperationStatus) {
- `Task function operation '${
- message.taskFunctionOperation as string
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- }' failed on worker ${message.workerId} with error: '${
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- message.workerError!.message
- }'`
+ `Task function operation '${message.taskFunctionOperation}' failed on worker ${message.workerId} with error: '${message.workerError?.message}'`
new Error(
`Task function operation '${
message.taskFunctionOperation as string
new Error(
`Task function operation '${
message.taskFunctionOperation as string
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- }' failed on worker ${errorResponse!
- .workerId!} with error: '${
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- errorResponse!.workerError!.message
+ }' failed on worker ${errorResponse?.workerId} with error: '${
+ errorResponse?.workerError?.message
private async sendKillMessageToWorker (workerNodeKey: number): Promise<void> {
await new Promise<void>((resolve, reject) => {
private async sendKillMessageToWorker (workerNodeKey: number): Promise<void> {
await new Promise<void>((resolve, reject) => {
- if (this.workerNodes?.[workerNodeKey] == null) {
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
+ if (this.workerNodes[workerNodeKey] == null) {
} else if (message.kill === 'failure') {
reject(
new Error(
} else if (message.kill === 'failure') {
reject(
new Error(
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- `Kill message handling failed on worker ${message.workerId!}`
+ `Kill message handling failed on worker ${message.workerId}`
workerNodeKey: number,
task: Task<Data>
): void {
workerNodeKey: number,
task: Task<Data>
): void {
- if (this.workerNodes[workerNodeKey]?.usage != null) {
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
+ if (this.workerNodes[workerNodeKey].usage != null) {
const workerUsage = this.workerNodes[workerNodeKey].usage
++workerUsage.tasks.executing
updateWaitTimeWorkerUsage(
const workerUsage = this.workerNodes[workerNodeKey].usage
++workerUsage.tasks.executing
updateWaitTimeWorkerUsage(
message: MessageValue<Response>
): void {
let needWorkerChoiceStrategyUpdate = false
message: MessageValue<Response>
): void {
let needWorkerChoiceStrategyUpdate = false
- if (this.workerNodes[workerNodeKey]?.usage != null) {
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
+ if (this.workerNodes[workerNodeKey].usage != null) {
const workerUsage = this.workerNodes[workerNodeKey].usage
updateTaskStatisticsWorkerUsage(workerUsage, message)
updateRunTimeWorkerUsage(
const workerUsage = this.workerNodes[workerNodeKey].usage
updateTaskStatisticsWorkerUsage(workerUsage, message)
updateRunTimeWorkerUsage(
needWorkerChoiceStrategyUpdate = true
}
if (needWorkerChoiceStrategyUpdate) {
needWorkerChoiceStrategyUpdate = true
}
if (needWorkerChoiceStrategyUpdate) {
- this.workerChoiceStrategyContext.update(workerNodeKey)
+ this.workerChoiceStrategyContext?.update(workerNodeKey)
private shallUpdateTaskFunctionWorkerUsage (workerNodeKey: number): boolean {
const workerInfo = this.getWorkerInfo(workerNodeKey)
return (
private shallUpdateTaskFunctionWorkerUsage (workerNodeKey: number): boolean {
const workerInfo = this.getWorkerInfo(workerNodeKey)
return (
Array.isArray(workerInfo.taskFunctionNames) &&
workerInfo.taskFunctionNames.length > 2
)
Array.isArray(workerInfo.taskFunctionNames) &&
workerInfo.taskFunctionNames.length > 2
)
if (this.shallCreateDynamicWorker()) {
const workerNodeKey = this.createAndSetupDynamicWorkerNode()
if (
if (this.shallCreateDynamicWorker()) {
const workerNodeKey = this.createAndSetupDynamicWorkerNode()
if (
- this.workerChoiceStrategyContext.getStrategyPolicy().dynamicWorkerUsage
+ this.workerChoiceStrategyContext?.getStrategyPolicy()
+ .dynamicWorkerUsage === true
) {
return workerNodeKey
}
}
) {
return workerNodeKey
}
}
- return this.workerChoiceStrategyContext.execute()
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ return this.workerChoiceStrategyContext!.execute()!
) {
this.redistributeQueuedTasks(this.workerNodes.indexOf(workerNode))
}
) {
this.redistributeQueuedTasks(this.workerNodes.indexOf(workerNode))
}
- workerNode?.terminate().catch(error => {
+ workerNode.terminate().catch(error => {
this.emitter?.emit(PoolEvents.error, error)
})
})
this.emitter?.emit(PoolEvents.error, error)
})
})
const workerNode = this.workerNodes[workerNodeKey]
workerNode.info.dynamic = true
if (
const workerNode = this.workerNodes[workerNodeKey]
workerNode.info.dynamic = true
if (
- this.workerChoiceStrategyContext.getStrategyPolicy().dynamicWorkerReady ||
- this.workerChoiceStrategyContext.getStrategyPolicy().dynamicWorkerUsage
+ this.workerChoiceStrategyContext?.getStrategyPolicy()
+ .dynamicWorkerReady === true ||
+ this.workerChoiceStrategyContext?.getStrategyPolicy()
+ .dynamicWorkerUsage === true
) {
workerNode.info.ready = true
}
) {
workerNode.info.ready = true
}
this.sendToWorker(workerNodeKey, {
statistics: {
runTime:
this.sendToWorker(workerNodeKey, {
statistics: {
runTime:
- this.workerChoiceStrategyContext.getTaskStatisticsRequirements()
- .runTime.aggregate,
- elu: this.workerChoiceStrategyContext.getTaskStatisticsRequirements()
- .elu.aggregate
+ this.workerChoiceStrategyContext?.getTaskStatisticsRequirements()
+ ?.runTime.aggregate ?? false,
+ elu:
+ this.workerChoiceStrategyContext?.getTaskStatisticsRequirements()?.elu
+ .aggregate ?? false
taskName: string
): void {
const workerNode = this.workerNodes[workerNodeKey]
taskName: string
): void {
const workerNode = this.workerNodes[workerNodeKey]
- if (workerNode?.usage != null) {
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
+ if (workerNode.usage != null) {
++workerNode.usage.tasks.stolen
}
if (
++workerNode.usage.tasks.stolen
}
if (
workerNodeKey: number
): void {
const workerNode = this.workerNodes[workerNodeKey]
workerNodeKey: number
): void {
const workerNode = this.workerNodes[workerNodeKey]
- if (workerNode?.usage != null) {
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
+ if (workerNode.usage != null) {
++workerNode.usage.tasks.sequentiallyStolen
}
}
++workerNode.usage.tasks.sequentiallyStolen
}
}
workerNodeKey: number
): void {
const workerNode = this.workerNodes[workerNodeKey]
workerNodeKey: number
): void {
const workerNode = this.workerNodes[workerNodeKey]
- if (workerNode?.usage != null) {
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
+ if (workerNode.usage != null) {
workerNode.usage.tasks.sequentiallyStolen = 0
}
}
workerNode.usage.tasks.sequentiallyStolen = 0
}
}
const { workerNodeKey } = eventDetail
if (workerNodeKey == null) {
throw new Error(
const { workerNodeKey } = eventDetail
if (workerNodeKey == null) {
throw new Error(
- 'WorkerNode event detail workerNodeKey property must be defined'
+ "WorkerNode event detail 'workerNodeKey' property must be defined"
+ const workerInfo = this.getWorkerInfo(workerNodeKey)
if (
this.cannotStealTask() ||
if (
this.cannotStealTask() ||
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- this.info.stealingWorkerNodes! > Math.floor(this.workerNodes.length / 2)
+ (this.info.stealingWorkerNodes ?? 0) >
+ Math.floor(this.workerNodes.length / 2)
) {
if (previousStolenTask != null) {
) {
if (previousStolenTask != null) {
- this.getWorkerInfo(workerNodeKey).stealing = false
+ workerInfo.stealing = false
(workerNodeTasksUsage.executing > 0 ||
this.tasksQueueSize(workerNodeKey) > 0)
) {
(workerNodeTasksUsage.executing > 0 ||
this.tasksQueueSize(workerNodeKey) > 0)
) {
- this.getWorkerInfo(workerNodeKey).stealing = false
+ workerInfo.stealing = false
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
for (const taskName of this.workerNodes[workerNodeKey].info
.taskFunctionNames!) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
for (const taskName of this.workerNodes[workerNodeKey].info
.taskFunctionNames!) {
this.resetTaskSequentiallyStolenStatisticsWorkerUsage(workerNodeKey)
return
}
this.resetTaskSequentiallyStolenStatisticsWorkerUsage(workerNodeKey)
return
}
- this.getWorkerInfo(workerNodeKey).stealing = true
+ workerInfo.stealing = true
const stolenTask = this.workerNodeStealTask(workerNodeKey)
if (
this.shallUpdateTaskFunctionWorkerUsage(workerNodeKey) &&
const stolenTask = this.workerNodeStealTask(workerNodeKey)
if (
this.shallUpdateTaskFunctionWorkerUsage(workerNodeKey) &&
): void => {
if (
this.cannotStealTask() ||
): void => {
if (
this.cannotStealTask() ||
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- this.info.stealingWorkerNodes! > Math.floor(this.workerNodes.length / 2)
+ (this.info.stealingWorkerNodes ?? 0) >
+ Math.floor(this.workerNodes.length / 2)
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
this.opts.tasksQueueOptions!.size! - sizeOffset
) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
this.opts.tasksQueueOptions!.size! - sizeOffset
) {
- this.getWorkerInfo(workerNodeKey).stealing = true
+ const workerInfo = this.getWorkerInfo(workerNodeKey)
+ workerInfo.stealing = true
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const task = sourceWorkerNode.popTask()!
this.handleTask(workerNodeKey, task)
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
this.updateTaskStolenStatisticsWorkerUsage(workerNodeKey, task.name!)
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const task = sourceWorkerNode.popTask()!
this.handleTask(workerNodeKey, task)
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
this.updateTaskStolenStatisticsWorkerUsage(workerNodeKey, task.name!)
- this.getWorkerInfo(workerNodeKey).stealing = false
+ workerInfo.stealing = false
private handleWorkerReadyResponse (message: MessageValue<Response>): void {
const { workerId, ready, taskFunctionNames } = message
if (ready == null || !ready) {
private handleWorkerReadyResponse (message: MessageValue<Response>): void {
const { workerId, ready, taskFunctionNames } = message
if (ready == null || !ready) {
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- throw new Error(`Worker ${workerId!} failed to initialize`)
+ throw new Error(`Worker ${workerId} failed to initialize`)
}
const workerNode =
this.workerNodes[this.getWorkerNodeKeyByWorkerId(workerId)]
}
const workerNode =
this.workerNodes[this.getWorkerNodeKeyByWorkerId(workerId)]
this.afterTaskExecutionHook(workerNodeKey, message)
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
this.promiseResponseMap.delete(taskId!)
this.afterTaskExecutionHook(workerNodeKey, message)
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
this.promiseResponseMap.delete(taskId!)
- workerNode?.emit('taskFinished', taskId)
+ workerNode.emit('taskFinished', taskId)
if (this.opts.enableTasksQueue === true && !this.destroying) {
const workerNodeTasksUsage = workerNode.usage.tasks
if (
if (this.opts.enableTasksQueue === true && !this.destroying) {
const workerNodeTasksUsage = workerNode.usage.tasks
if (
* @returns The worker information.
*/
protected getWorkerInfo (workerNodeKey: number): WorkerInfo {
* @returns The worker information.
*/
protected getWorkerInfo (workerNodeKey: number): WorkerInfo {
- return this.workerNodes[workerNodeKey]?.info
+ const workerInfo = this.workerNodes[workerNodeKey]?.info
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
+ if (workerInfo == null) {
+ throw new Error(`Worker node with key '${workerNodeKey}' not found`)
+ }
+ return workerInfo
const workerNodeKey = this.workerNodes.indexOf(workerNode)
if (workerNodeKey !== -1) {
this.workerNodes.splice(workerNodeKey, 1)
const workerNodeKey = this.workerNodes.indexOf(workerNode)
if (workerNodeKey !== -1) {
this.workerNodes.splice(workerNodeKey, 1)
- this.workerChoiceStrategyContext.remove(workerNodeKey)
+ this.workerChoiceStrategyContext?.remove(workerNodeKey)
super(min, filePath, opts, max)
checkDynamicPoolSize(
this.minimumNumberOfWorkers,
super(min, filePath, opts, max)
checkDynamicPoolSize(
this.minimumNumberOfWorkers,
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- this.maximumNumberOfWorkers!
+ this.maximumNumberOfWorkers
): void {
this.workerNodes[workerNodeKey].worker.send({
...message,
): void {
this.workerNodes[workerNodeKey].worker.send({
...message,
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- workerId: this.getWorkerInfo(workerNodeKey).id!
+ workerId: this.getWorkerInfo(workerNodeKey).id
/**
* The previous worker node key.
*/
/**
* The previous worker node key.
*/
- protected previousWorkerNodeKey: number = 0
+ protected previousWorkerNodeKey = 0
/** @inheritDoc */
public readonly strategyPolicy: StrategyPolicy = {
/** @inheritDoc */
public readonly strategyPolicy: StrategyPolicy = {
- private roundId: number = 0
- private workerNodeId: number = 0
+ private workerNodeId = 0
/**
* Worker node virtual task runtime.
*/
/**
* Worker node virtual task runtime.
*/
- private workerNodeVirtualTaskRunTime: number = 0
+ private workerNodeVirtualTaskRunTime = 0
/** @inheritDoc */
public constructor (
/** @inheritDoc */
public constructor (
/**
* Worker node virtual task runtime.
*/
/**
* Worker node virtual task runtime.
*/
- private workerNodeVirtualTaskRunTime: number = 0
+ private workerNodeVirtualTaskRunTime = 0
/** @inheritDoc */
public constructor (
/** @inheritDoc */
public constructor (
super(min, filePath, opts, max)
checkDynamicPoolSize(
this.minimumNumberOfWorkers,
super(min, filePath, opts, max)
checkDynamicPoolSize(
this.minimumNumberOfWorkers,
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- this.maximumNumberOfWorkers!
+ this.maximumNumberOfWorkers
message: MessageValue<Data>,
transferList?: TransferListItem[]
): void {
message: MessageValue<Data>,
transferList?: TransferListItem[]
): void {
- this.workerNodes[workerNodeKey].messageChannel?.port1?.postMessage(
+ this.workerNodes[workerNodeKey].messageChannel?.port1.postMessage(
{ ...message, workerId: this.getWorkerInfo(workerNodeKey).id },
transferList
)
{ ...message, workerId: this.getWorkerInfo(workerNodeKey).id },
transferList
)
workerNodeKey: number,
listener: (message: MessageValue<Message>) => void
): void {
workerNodeKey: number,
listener: (message: MessageValue<Message>) => void
): void {
- this.workerNodes[workerNodeKey].messageChannel?.port1?.on(
+ this.workerNodes[workerNodeKey].messageChannel?.port1.on(
workerNodeKey: number,
listener: (message: MessageValue<Message>) => void
): void {
workerNodeKey: number,
listener: (message: MessageValue<Message>) => void
): void {
- this.workerNodes[workerNodeKey].messageChannel?.port1?.once(
+ this.workerNodes[workerNodeKey].messageChannel?.port1.once(
workerNodeKey: number,
listener: (message: MessageValue<Message>) => void
): void {
workerNodeKey: number,
listener: (message: MessageValue<Message>) => void
): void {
- this.workerNodes[workerNodeKey].messageChannel?.port1?.off(
+ this.workerNodes[workerNodeKey].messageChannel?.port1.off(
-export const checkFilePath = (filePath: string): void => {
+export const checkFilePath = (filePath: string | undefined): void => {
if (filePath == null) {
throw new TypeError('The worker file path must be specified')
}
if (filePath == null) {
throw new TypeError('The worker file path must be specified')
}
-export const checkDynamicPoolSize = (min: number, max: number): void => {
+export const checkDynamicPoolSize = (
+ min: number,
+ max: number | undefined
+): void => {
if (max == null) {
throw new TypeError(
'Cannot instantiate a dynamic pool without specifying the maximum pool size'
if (max == null) {
throw new TypeError(
'Cannot instantiate a dynamic pool without specifying the maximum pool size'
}
export const checkValidWorkerChoiceStrategy = (
}
export const checkValidWorkerChoiceStrategy = (
- workerChoiceStrategy: WorkerChoiceStrategy
+ workerChoiceStrategy: WorkerChoiceStrategy | undefined
): void => {
if (
workerChoiceStrategy != null &&
): void => {
if (
workerChoiceStrategy != null &&
}
export const checkValidTasksQueueOptions = (
}
export const checkValidTasksQueueOptions = (
- tasksQueueOptions: TasksQueueOptions
+ tasksQueueOptions: TasksQueueOptions | undefined
): void => {
if (tasksQueueOptions != null && !isPlainObject(tasksQueueOptions)) {
throw new TypeError('Invalid tasks queue options: must be a plain object')
): void => {
if (tasksQueueOptions != null && !isPlainObject(tasksQueueOptions)) {
throw new TypeError('Invalid tasks queue options: must be a plain object')
}
export const checkWorkerNodeArguments = (
}
export const checkWorkerNodeArguments = (
- type: WorkerType,
- filePath: string,
- opts: WorkerNodeOptions
+ type: WorkerType | undefined,
+ filePath: string | undefined,
+ opts: WorkerNodeOptions | undefined
): void => {
if (type == null) {
throw new TypeError('Cannot construct a worker node without a worker type')
): void => {
if (type == null) {
throw new TypeError('Cannot construct a worker node without a worker type')
*/
const updateMeasurementStatistics = (
measurementStatistics: MeasurementStatistics,
*/
const updateMeasurementStatistics = (
measurementStatistics: MeasurementStatistics,
- measurementRequirements: MeasurementStatisticsRequirements,
- measurementValue: number
+ measurementRequirements: MeasurementStatisticsRequirements | undefined,
+ measurementValue: number | undefined
- if (measurementRequirements.aggregate) {
+ if (
+ measurementRequirements != null &&
+ measurementValue != null &&
+ measurementRequirements.aggregate
+ ) {
measurementStatistics.aggregate =
(measurementStatistics.aggregate ?? 0) + measurementValue
measurementStatistics.minimum = min(
measurementStatistics.aggregate =
(measurementStatistics.aggregate ?? 0) + measurementValue
measurementStatistics.minimum = min(
measurementValue,
measurementStatistics.maximum ?? -Infinity
)
measurementValue,
measurementStatistics.maximum ?? -Infinity
)
- if (
- (measurementRequirements.average || measurementRequirements.median) &&
- measurementValue != null
- ) {
+ if (measurementRequirements.average || measurementRequirements.median) {
measurementStatistics.history.push(measurementValue)
if (measurementRequirements.average) {
measurementStatistics.average = average(measurementStatistics.history)
measurementStatistics.history.push(measurementValue)
if (measurementRequirements.average) {
measurementStatistics.average = average(measurementStatistics.history)
Data = unknown,
Response = unknown
>(
Data = unknown,
Response = unknown
>(
- workerChoiceStrategyContext: WorkerChoiceStrategyContext<
- Worker,
- Data,
- Response
- >,
+ workerChoiceStrategyContext:
+ | WorkerChoiceStrategyContext<Worker, Data, Response>
+ | undefined,
workerUsage: WorkerUsage,
task: Task<Data>
): void => {
workerUsage: WorkerUsage,
task: Task<Data>
): void => {
const taskWaitTime = timestamp - (task.timestamp ?? timestamp)
updateMeasurementStatistics(
workerUsage.waitTime,
const taskWaitTime = timestamp - (task.timestamp ?? timestamp)
updateMeasurementStatistics(
workerUsage.waitTime,
- workerChoiceStrategyContext.getTaskStatisticsRequirements().waitTime,
+ workerChoiceStrategyContext?.getTaskStatisticsRequirements()?.waitTime,
): void => {
const workerTaskStatistics = workerUsage.tasks
if (
): void => {
const workerTaskStatistics = workerUsage.tasks
if (
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
workerTaskStatistics.executing != null &&
workerTaskStatistics.executing > 0
) {
workerTaskStatistics.executing != null &&
workerTaskStatistics.executing > 0
) {
Data = unknown,
Response = unknown
>(
Data = unknown,
Response = unknown
>(
- workerChoiceStrategyContext: WorkerChoiceStrategyContext<
- Worker,
- Data,
- Response
- >,
+ workerChoiceStrategyContext:
+ | WorkerChoiceStrategyContext<Worker, Data, Response>
+ | undefined,
workerUsage: WorkerUsage,
message: MessageValue<Response>
): void => {
workerUsage: WorkerUsage,
message: MessageValue<Response>
): void => {
}
updateMeasurementStatistics(
workerUsage.runTime,
}
updateMeasurementStatistics(
workerUsage.runTime,
- workerChoiceStrategyContext.getTaskStatisticsRequirements().runTime,
+ workerChoiceStrategyContext?.getTaskStatisticsRequirements()?.runTime,
message.taskPerformance?.runTime ?? 0
)
}
message.taskPerformance?.runTime ?? 0
)
}
Data = unknown,
Response = unknown
>(
Data = unknown,
Response = unknown
>(
- workerChoiceStrategyContext: WorkerChoiceStrategyContext<
- Worker,
- Data,
- Response
- >,
+ workerChoiceStrategyContext:
+ | WorkerChoiceStrategyContext<Worker, Data, Response>
+ | undefined,
workerUsage: WorkerUsage,
message: MessageValue<Response>
): void => {
if (message.workerError != null) {
return
}
workerUsage: WorkerUsage,
message: MessageValue<Response>
): void => {
if (message.workerError != null) {
return
}
- const eluTaskStatisticsRequirements: MeasurementStatisticsRequirements =
- workerChoiceStrategyContext.getTaskStatisticsRequirements().elu
+ const eluTaskStatisticsRequirements =
+ workerChoiceStrategyContext?.getTaskStatisticsRequirements()?.elu
updateMeasurementStatistics(
workerUsage.elu.active,
eluTaskStatisticsRequirements,
updateMeasurementStatistics(
workerUsage.elu.active,
eluTaskStatisticsRequirements,
eluTaskStatisticsRequirements,
message.taskPerformance?.elu?.idle ?? 0
)
eluTaskStatisticsRequirements,
message.taskPerformance?.elu?.idle ?? 0
)
- if (eluTaskStatisticsRequirements.aggregate) {
+ if (eluTaskStatisticsRequirements?.aggregate === true) {
if (message.taskPerformance?.elu != null) {
if (workerUsage.elu.utilization != null) {
workerUsage.elu.utilization =
if (message.taskPerformance?.elu != null) {
if (workerUsage.elu.utilization != null) {
workerUsage.elu.utilization =
case WorkerTypes.thread:
return new Worker(filePath, {
env: SHARE_ENV,
case WorkerTypes.thread:
return new Worker(filePath, {
env: SHARE_ENV,
}) as unknown as Worker
case WorkerTypes.cluster:
}) as unknown as Worker
case WorkerTypes.cluster:
- return cluster.fork(opts?.env) as unknown as Worker
+ 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}'`)
default:
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
throw new Error(`Unknown worker type '${type}'`)
if (this.info.type === WorkerTypes.thread) {
this.messageChannel = new MessageChannel()
}
if (this.info.type === WorkerTypes.thread) {
this.messageChannel = new MessageChannel()
}
- this.tasksQueueBackPressureSize = opts.tasksQueueBackPressureSize
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ this.tasksQueueBackPressureSize = opts.tasksQueueBackPressureSize!
this.tasksQueue = new Deque<Task<Data>>()
this.onBackPressureStarted = false
this.taskFunctionsUsage = new Map<string, WorkerUsage>()
this.tasksQueue = new Deque<Task<Data>>()
this.onBackPressureStarted = false
this.taskFunctionsUsage = new Map<string, WorkerUsage>()
export interface WorkerNodeOptions {
workerOptions?: WorkerOptions
env?: Record<string, unknown>
export interface WorkerNodeOptions {
workerOptions?: WorkerOptions
env?: Record<string, unknown>
- tasksQueueBackPressureSize: number
+ tasksQueueBackPressureSize: number | undefined
export const isPlainObject = (obj: unknown): boolean =>
typeof obj === 'object' &&
obj !== null &&
export const isPlainObject = (obj: unknown): boolean =>
typeof obj === 'object' &&
obj !== null &&
- obj?.constructor === Object &&
+ obj.constructor === Object &&
Object.prototype.toString.call(obj) === '[object Object]'
/**
Object.prototype.toString.call(obj) === '[object Object]'
/**
): ((...args: A) => R) => {
let result: R
return (...args: A) => {
): ((...args: A) => R) => {
let result: R
return (...args: A) => {
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (fn != null) {
result = fn.apply<T, A, R>(context, args)
;(fn as unknown as undefined) = (context as unknown as undefined) =
if (fn != null) {
result = fn.apply<T, A, R>(context, args)
;(fn as unknown as undefined) = (context as unknown as undefined) =
opts?: WorkerChoiceStrategyOptions
): WorkerChoiceStrategyOptions => {
opts = clone(opts ?? {})
opts?: WorkerChoiceStrategyOptions
): WorkerChoiceStrategyOptions => {
opts = clone(opts ?? {})
- opts.weights = opts?.weights ?? getDefaultWeights(pool.info.maxSize)
+ opts.weights = opts.weights ?? getDefaultWeights(pool.info.maxSize)
return {
...{
runTime: { median: false },
return {
...{
runTime: { median: false },
const cpuSpeed = randomInt(500, 2500)
let cpusCycleTimeWeight = 0
for (const cpu of cpus()) {
const cpuSpeed = randomInt(500, 2500)
let cpusCycleTimeWeight = 0
for (const cpu of cpus()) {
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (cpu.speed == null || cpu.speed === 0) {
cpu.speed =
if (cpu.speed == null || cpu.speed === 0) {
cpu.speed =
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
cpus().find(cpu => cpu.speed != null && cpu.speed !== 0)?.speed ??
cpuSpeed
}
cpus().find(cpu => cpu.speed != null && cpu.speed !== 0)?.speed ??
cpuSpeed
}
/**
* Performance statistics computation requirements.
*/
/**
* Performance statistics computation requirements.
*/
- protected statistics!: WorkerStatistics
+ protected statistics?: WorkerStatistics
/**
* Handler id of the `activeInterval` worker activity check.
*/
/**
* Handler id of the `activeInterval` worker activity check.
*/
* @param opts - Options for the worker.
*/
public constructor (
* @param opts - Options for the worker.
*/
public constructor (
- protected readonly isMain: boolean,
- private readonly mainWorker: MainWorker,
+ protected readonly isMain: boolean | undefined,
+ private readonly mainWorker: MainWorker | undefined | null,
taskFunctions: TaskFunction<Data, Response> | TaskFunctions<Data, Response>,
protected opts: WorkerOptions = DEFAULT_WORKER_OPTIONS
) {
taskFunctions: TaskFunction<Data, Response> | TaskFunctions<Data, Response>,
protected opts: WorkerOptions = DEFAULT_WORKER_OPTIONS
) {
* @param taskFunctions - The task function(s) parameter that should be checked.
*/
private checkTaskFunctions (
* @param taskFunctions - The task function(s) parameter that should be checked.
*/
private checkTaskFunctions (
- taskFunctions: TaskFunction<Data, Response> | TaskFunctions<Data, Response>
+ taskFunctions:
+ | TaskFunction<Data, Response>
+ | TaskFunctions<Data, Response>
+ | undefined
): void {
if (taskFunctions == null) {
throw new Error('taskFunctions parameter is mandatory')
): void {
if (taskFunctions == null) {
throw new Error('taskFunctions parameter is mandatory')
taskFunctionOperationStatus: response.status,
taskFunctionName,
...(!response.status &&
taskFunctionOperationStatus: response.status,
taskFunctionName,
...(!response.status &&
- response?.error != null && {
+ response.error != null && {
workerError: {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
name: taskFunctionName!,
workerError: {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
name: taskFunctionName!,
protected handleKillMessage (_message: MessageValue<Data>): void {
this.stopCheckActive()
if (isAsyncFunction(this.opts.killHandler)) {
protected handleKillMessage (_message: MessageValue<Data>): void {
this.stopCheckActive()
if (isAsyncFunction(this.opts.killHandler)) {
- (this.opts.killHandler?.() as Promise<void>)
+ (this.opts.killHandler() as Promise<void>)
.then(() => {
this.sendToMainWorker({ kill: 'success' })
return undefined
.then(() => {
this.sendToMainWorker({ kill: 'success' })
return undefined
workerError: {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
name: name!,
workerError: {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
name: name!,
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- message: `Task function '${name!}' not found`,
+ message: `Task function '${name}' not found`,
}
private beginTaskPerformance (name?: string): TaskPerformance {
}
private beginTaskPerformance (name?: string): TaskPerformance {
+ if (this.statistics == null) {
+ throw new Error('Performance statistics computation requirements not set')
+ }
return {
name: name ?? DEFAULT_TASK_NAME,
timestamp: performance.now(),
return {
name: name ?? DEFAULT_TASK_NAME,
timestamp: performance.now(),
- ...(this.statistics.elu && { elu: performance.eventLoopUtilization() })
+ ...(this.statistics.elu && {
+ elu: performance.eventLoopUtilization()
+ })
}
}
private endTaskPerformance (
taskPerformance: TaskPerformance
): TaskPerformance {
}
}
private endTaskPerformance (
taskPerformance: TaskPerformance
): TaskPerformance {
+ if (this.statistics == null) {
+ throw new Error('Performance statistics computation requirements not set')
+ }
return {
...taskPerformance,
...(this.statistics.runTime && {
return {
...taskPerformance,
...(this.statistics.runTime && {
- private checkStatistics (): void {
- if (this.statistics == null) {
- throw new Error('Performance statistics computation requirements not set')
- }
- }
-
private updateLastTaskTimestamp (): void {
if (this.activeInterval != null) {
this.lastTaskTimestamp = performance.now()
private updateLastTaskTimestamp (): void {
if (this.activeInterval != null) {
this.lastTaskTimestamp = performance.now()
taskFunctions: TaskFunction<Data, Response> | TaskFunctions<Data, Response>,
opts: WorkerOptions = {}
) {
taskFunctions: TaskFunction<Data, Response> | TaskFunctions<Data, Response>,
opts: WorkerOptions = {}
) {
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- super(cluster.isPrimary, cluster.worker!, taskFunctions, opts)
+ super(cluster.isPrimary, cluster.worker, taskFunctions, opts)
taskFunctions: TaskFunction<Data, Response> | TaskFunctions<Data, Response>,
opts: WorkerOptions = {}
) {
taskFunctions: TaskFunction<Data, Response> | TaskFunctions<Data, Response>,
opts: WorkerOptions = {}
) {
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- super(isMainThread, parentPort!, taskFunctions, opts)
+ super(isMainThread, parentPort, taskFunctions, opts)
import type { TaskFunction } from './task-functions.js'
import { KillBehaviors, type WorkerOptions } from './worker-options.js'
import type { TaskFunction } from './task-functions.js'
import { KillBehaviors, type WorkerOptions } from './worker-options.js'
-export const checkValidWorkerOptions = (opts: WorkerOptions): void => {
+export const checkValidWorkerOptions = (
+ opts: WorkerOptions | undefined
+): void => {
if (opts != null && !isPlainObject(opts)) {
throw new TypeError('opts worker options parameter is not a plain object')
}
if (opts != null && !isPlainObject(opts)) {
throw new TypeError('opts worker options parameter is not a plain object')
}
expect(
createWorker(
WorkerTypes.thread,
expect(
createWorker(
WorkerTypes.thread,
- './tests/worker-files/thread/testWorker.mjs'
+ './tests/worker-files/thread/testWorker.mjs',
+ {}
)
).toBeInstanceOf(ThreadWorker)
expect(
createWorker(
WorkerTypes.cluster,
)
).toBeInstanceOf(ThreadWorker)
expect(
createWorker(
WorkerTypes.cluster,
- './tests/worker-files/cluster/testWorker.mjs'
+ './tests/worker-files/cluster/testWorker.mjs',
+ {}
)
).toBeInstanceOf(ClusterWorker)
})
)
).toBeInstanceOf(ClusterWorker)
})