Only allow primitive JSON for transfer between worker and main worker (#128)
[poolifier.git] / src / worker / cluster-worker.ts
1 import type { Worker } from 'cluster'
2 import { isMaster, worker } from 'cluster'
3 import type { JSONValue, MessageValue } from '../utility-types'
4 import { AbstractWorker } from './abstract-worker'
5 import type { WorkerOptions } from './worker-options'
6
7 /**
8 * An example worker that will be always alive, you just need to **extend** this class if you want a static pool.
9 *
10 * When this worker is inactive for more than 1 minute, it will send this info to the main worker,
11 * if you are using DynamicClusterPool, the workers created after will be killed, the min num of worker will be guaranteed.
12 *
13 * @author [Christopher Quadflieg](https://github.com/Shinigami92)
14 * @since 2.0.0
15 */
16 export class ClusterWorker<
17 Data extends JSONValue = JSONValue,
18 Response extends JSONValue = JSONValue
19 > extends AbstractWorker<Worker, Data, Response> {
20 public constructor (fn: (data: Data) => Response, opts: WorkerOptions = {}) {
21 super('worker-cluster-pool:pioardi', isMaster, fn, opts)
22
23 worker.on('message', (value: MessageValue<Data>) => {
24 if (value?.data && value.id) {
25 // here you will receive messages
26 // console.log('This is the main worker ' + isMain)
27 if (this.async) {
28 this.runInAsyncScope(this.runAsync.bind(this), this, fn, value)
29 } else {
30 this.runInAsyncScope(this.run.bind(this), this, fn, value)
31 }
32 } else if (value.kill) {
33 // here is time to kill this worker, just clearing the interval
34 if (this.interval) clearInterval(this.interval)
35 this.emitDestroy()
36 }
37 })
38 }
39
40 protected getMainWorker (): Worker {
41 return worker
42 }
43
44 protected sendToMainWorker (message: MessageValue<Response>): void {
45 this.getMainWorker().send(message)
46 }
47
48 protected handleError (e: Error | string): string {
49 return e instanceof Error ? e.message : e
50 }
51 }