node-serialport: Serial port commnunication does not work inside a Worker Thread

Summary of Problem

Opening a serial port from within a worker thread fails with:

Error: Module did not self-register.

Code to Reproduce the Issue

github repo: hugo-a-garcia/serial-worker

const {
   Worker, isMainThread, parentPort, workerData
} = require('worker_threads');

const SerialPort = require("serialport");
   const Readline = SerialPort.parsers.Readline;

if (isMainThread) {
   console.log("In main thread");

   const worker = new Worker(__filename);
   worker.on('message', msg => {
      console.log(msg);
   });
   worker.on('error', err => {
      console.error("Oops " + err)
   });
   worker.on('exit', (code) => {
      if (code !== 0)
         console.log(`Worker stopped with exit code ${code}`);
   });

} else {
   console.log("In worker thread");
 
   const port = new SerialPort("/dev/ttyACM0", {
       baudRate: 9600
   });
   
   const parser = new Readline
   port.pipe(parser);
   parser.on("data", (data) => console.log(data));
   
   // port.on('readable', function () {
   //     console.log(port.read().toString());
   // });
   
   port.on('error', function (err) {
       console.log('Error: ', err.message);
   });

   parentPort.postMessage("Done.");
}

Versions, Operating System and Hardware

  • SerialPort@? 7.1.5
  • Node.js v? v12.9.1
  • Linux
  • Hardware and chipset? Arduino Uno connected to laptop

Possible related issue: N-API support for node-serialport #1186

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 1
  • Comments: 17 (6 by maintainers)

Most upvoted comments

Got to start moving to NAPI anyway 🤷‍♂️

Not a bug in Node.js. 😃 Quoting the Worker threads documentation:

Native add-ons can only be loaded from multiple threads if they fulfill certain conditions.

In short, your addon needs to be declared as context-aware and support multiple threads natively. For N-API, it’s assumed that that’s the case.

Just taking a quick look at the source code here, at least the usage of uv_default_loop() is problematic and will mean that the code won’t work on worker threads as-is anyway.

Based on the discussion, it sounds like migration from NAN to N-API is a stepping stone to resolving this. Is that still understood to be the case?

I believe there was a previous endevour to migrate to N-API https://github.com/serialport/node-serialport/issues/1186

While that attempt was a while ago, I wonder what code or lessons can be gleaned from that previous work?

We landed napi support and support workers as of 2 years ago.

Really tried to understand what has to be done to implement the cleanupHooks, but actually I’m lost in all this c++. This is not my domain 😃 I now forward all calls from workers to serial port running in the main thread using the message channel. This is pretty ugly but I’m fine with it at the moment 😇