-import { AsyncResource } from 'node:async_hooks'
import type { Worker } from 'node:cluster'
import type { MessagePort } from 'node:worker_threads'
import { performance } from 'node:perf_hooks'
MainWorker extends Worker | MessagePort,
Data = unknown,
Response = unknown
-> extends AsyncResource {
+> {
/**
* Worker id.
*/
* @param opts - Options for the worker.
*/
public constructor (
- type: string,
protected readonly isMain: boolean,
private readonly mainWorker: MainWorker,
taskFunctions: TaskFunction<Data, Response> | TaskFunctions<Data, Response>,
protected opts: WorkerOptions = DEFAULT_WORKER_OPTIONS
) {
- super(type)
if (this.isMain == null) {
throw new Error('isMain parameter is mandatory')
}
this.checkTaskFunctions(taskFunctions)
this.checkWorkerOptions(this.opts)
if (!this.isMain) {
+ // Should be once() but Node.js on windows has a bug that prevents it from working
this.getMainWorker().on('message', this.handleReadyMessage.bind(this))
}
}
*
* @param message - The kill message.
*/
- protected handleKillMessage (message: MessageValue<Data>): void {
+ protected handleKillMessage (_message: MessageValue<Data>): void {
this.stopCheckActive()
if (isAsyncFunction(this.opts.killHandler)) {
(this.opts.killHandler?.() as Promise<void>)
.then(() => {
this.sendToMainWorker({ kill: 'success' })
- return null
+ return undefined
})
.catch(() => {
this.sendToMainWorker({ kill: 'failure' })
})
- .finally(() => {
- this.emitDestroy()
- })
- .catch(EMPTY_FUNCTION)
} else {
try {
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
this.sendToMainWorker({ kill: 'success' })
} catch {
this.sendToMainWorker({ kill: 'failure' })
- } finally {
- this.emitDestroy()
}
}
}
private checkMessageWorkerId (message: MessageValue<Data>): void {
if (message.workerId == null) {
throw new Error('Message worker id is not set')
- } else if (message.workerId != null && message.workerId !== this.id) {
+ } else if (message.workerId !== this.id) {
throw new Error(
`Message worker id ${message.workerId} does not match the worker id ${this.id}`
)
*/
protected run (task: Task<Data>): void {
const { name, taskId, data } = task
- const fn = this.taskFunctions.get(name ?? DEFAULT_TASK_NAME)
- if (fn == null) {
+ const taskFunctionName = name ?? DEFAULT_TASK_NAME
+ if (!this.taskFunctions.has(taskFunctionName)) {
this.sendToMainWorker({
workerError: {
name: name as string,
})
return
}
+ const fn = this.taskFunctions.get(taskFunctionName)
if (isAsyncFunction(fn)) {
- this.runInAsyncScope(this.runAsync.bind(this), this, fn, task)
+ this.runAsync(fn as TaskAsyncFunction<Data, Response>, task)
} else {
- this.runInAsyncScope(this.runSync.bind(this), this, fn, task)
+ this.runSync(fn as TaskSyncFunction<Data, Response>, task)
}
}