josdejong / workerpool

Offload tasks to a pool of workers on node.js and in the browser
Apache License 2.0
2.06k stars 147 forks source link

TypeError: process.send is not a function #390

Closed thomasstjerne closed 1 year ago

thomasstjerne commented 1 year ago

Node version v18.12.1 with ES modules.

import { pool } from "workerpool";
import { dirname } from 'path';
import { fileURLToPath } from 'url';
const __dirname = dirname(fileURLToPath(import.meta.url));
const poolOfWorkers = pool(__dirname + '/myWorker.js');

poolOfWorkers.exec(aFunctionDefinedInMyWorker, params)
TypeError: process.send is not a function
    at worker.send (/......../node_modules/workerpool/src/worker.js:63:15)

https://github.com/josdejong/workerpool/blob/68b98633ed1a93eda4347f6761ef675a0d3beaad/src/worker.js#L63

josdejong commented 1 year ago

How to reproduce this issue? Can you share a minimal example that demonstrates the issue?

NickKelly1 commented 1 year ago

Had the same issue in NodeJS using worker threads.

Solution was to stop calling workerpool.worker(...) in the main thread. workerpool.worker tries to communicate with the main thread which breaks when executed from the main thread. It tries to use parentPort but that only exists on worker threads so the package falls back to process.send which doesn't exist either because the process wasn't spawned with an IPC channel, hence the error message.

For example:

package.json

{
  "type": "module",
  "dependencies": {
    "workerpool": "^6.4.0"
  }
}

main.js

// cjs
// const wt = require('worker_threads');
// const wp = require('workerpool');
// esm
import { fileURLToPath } from 'url';
import * as wt from 'worker_threads';
import wp from 'workerpool';

const ctx = wt.isMainThread ? '[main]' : '[worker]';
console.log(ctx);

// if (!wt.isMainThread) {
  wp.worker({
    work() { console.log(ctx, 'working'); }
  });
// }

if (wt.isMainThread) {
  // const thisFilename = __filename; // cjs
  const thisFilename = fileURLToPath(import.meta.url); // esm
  const pool = wp.pool(thisFilename, { workerType: 'thread', });
  pool
    .exec('work', null, { })
    .then(function() { console.log(ctx, 'done'); })
    .catch(function(err) { console.log(ctx, 'error', err); })
    .then(function() { pool.terminate(); })
}

execution

➜  example node main.js                  
[main]
.../example/node_modules/workerpool/src/worker.js:63
      process.send(message);
              ^

TypeError: process.send is not a function
    at worker.send (.../example/node_modules/workerpool/src/worker.js:63:15)
    at worker.register [as add] (.../example/node_modules/workerpool/src/worker.js:238:10)
    at Object.worker (.../example/node_modules/workerpool/src/index.js:22:10)
    at file:///.../example/main.js:13:6
    at ModuleJob.run (node:internal/modules/esm/module_job:192:25)

Node.js v20.2.0

Fixed by uncommenting the conditional // if (!wt.isMainThread) {

josdejong commented 1 year ago

Thanks for sharing Nick!

The workerpool.worker method is indeed only usable on the worker side, not in the main thread.

I'll close this issue now.

luluhoc commented 1 year ago

Just for anybody having this problem, for me it was that I accidentally exported a function and imported it in main thread 🔢