MCPcopy Create free account
hub / github.com/MultithreadedJSBook/code-samples / RpcWorkerPool

Class RpcWorkerPool

ch6-thread-pool/rpc-worker.js:5–66  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

3const STRATEGIES = new Set([ 'roundrobin', 'random', 'leastbusy' ]);
4
5module.exports = class RpcWorkerPool {
6 constructor(path, size = 0, strategy = 'roundrobin') {
7 if (size === 0) this.size = CORES; // <1>
8 else if (size < 0) this.size = Math.max(CORES + size, 1);
9 else this.size = size;
10
11 if (!STRATEGIES.has(strategy)) throw new TypeError('invalid strategy');
12 this.strategy = strategy; // <2>
13 this.rr_index = -1;
14
15 this.next_command_id = 0;
16 this.workers = []; // <3>
17 for (let i = 0; i < this.size; i++) {
18 const worker = new Worker(path);
19 this.workers.push({ worker, in_flight_commands: new Map() }); // <4>
20 worker.on('message', (msg) => {
21 this.onMessageHandler(msg, i);
22 });
23 }
24 }
25// THIS LINE SHOULD NOT APPEAR IN PRINT
26 onMessageHandler(msg, worker_id) {
27 const worker = this.workers[worker_id];
28 const { result, error, id } = msg;
29 const { resolve, reject } = worker.in_flight_commands.get(id);
30 worker.in_flight_commands.delete(id);
31 if (error) reject(error);
32 else resolve(result);
33 }
34// THIS LINE SHOULD NOT APPEAR IN PRINT
35 exec(method, ...args) {
36 const id = ++this.next_command_id;
37 let resolve, reject;
38 const promise = new Promise((res, rej) => { resolve = res; reject = rej; });
39 const worker = this.getWorker(); // <1>
40 worker.in_flight_commands.set(id, { resolve, reject });
41 worker.worker.postMessage({ method, params: args, id });
42 return promise;
43 }
44// THIS LINE SHOULD NOT APPEAR IN PRINT
45 getWorker() {
46 let id;
47 if (this.strategy === 'random') {
48 id = Math.floor(Math.random() * this.size);
49 } else if (this.strategy === 'roundrobin') {
50 this.rr_index++;
51 if (this.rr_index >= this.size) this.rr_index = 0;
52 id = this.rr_index;
53 } else if (this.strategy === 'leastbusy') {
54 let min = Infinity;
55 for (let i = 0; i < this.size; i++) {
56 let worker = this.workers[i];
57 if (worker.in_flight_commands.size < min) {
58 min = worker.in_flight_commands.size;
59 id = i;
60 }
61 }
62 }

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected