Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

serialport + electron, "close" event causes CPU spike #2323

Open
sabetts opened this issue Sep 27, 2021 · 4 comments
Open

serialport + electron, "close" event causes CPU spike #2323

sabetts opened this issue Sep 27, 2021 · 4 comments

Comments

@sabetts
Copy link

sabetts commented Sep 27, 2021

node 10.20.1

serial port 8.0.8

electron 13.1.7

platform: OSX 10.14.6

I open a serialport in electron's "main" process and use Electron's IPC functions to bridge between renderer and main process. main process opens a serial port and creates an event handler for "close" and "data" events. "data" events work fine and so does writing to the serial port. But if I unplug the USB plug, disconnecting the arduino from the computer, the "close" event does not fire. Instead I get a CPU spike in the electron process (as seen in Activity Monitor app).

@GazHank
Copy link
Contributor

GazHank commented Sep 29, 2021

Would you be able to share your project or example code? While I'm not able to test on Mac myself, if I can recreate the issue on another platform it might help get to the bottom of the problem

@maneetgoyal
Copy link

Getting the same problem. Using a BLuetooth legacy device. Pairing it with Bluettoth first and then connecting via Serial port. If I disconnect the Bluetooth connection, the close event is not firing.

If I manually close the serial port connection via https://serialport.io/docs/api-stream#close-1, it is getting fired.

@hspaay
Copy link

hspaay commented Nov 26, 2023

Seeing the same thing here using zwave-js.
After a successful initial connection, unplugging the Zwave USB stick does not trigger an onError event. Instead the CPU spikes and memory use creeps up until it consumes 5GB, then an exception occurs.

It is hard to share my application environment that uses zwave-js and you probably don't have a zwave USB stick handy so below this is what I've noticed:

Pausing the debugger while this is ongoing stops at 'unix-read.js'. See snippet below. Some observations:

  1. This section of code is recursing at breakneck speed, causing the CPU spike.
  2. The stack trace is too big to display but is basically a list of unixRead calls.
  3. binding.isOpen is true because the fd is still set, even though that port is closed.
  4. fsReadAsync returns without throwing an exception
  5. bytesRead is 0, which might explain the recursion. (not sure myself)

Speculation:
I suspect that normally readAsync would wait for data but as the port is closed it returns immediately. The code expects an exception to be thrown which doesn't happen in my case.

Maybe this is node dependent? This happens on:

  • node v16.20.2 and v20.10.0
  • ubuntu 23.10
  • serialport v12.0.0.
const unixRead = async ({ binding, buffer, offset, length, fsReadAsync = readAsync, }) => {
    logger('Starting read');
    if (!binding.isOpen || !binding.fd) {
        throw new errors_1.BindingsError('Port is not open', { canceled: true });
    }
    try {
        const { bytesRead } = await fsReadAsync(binding.fd, buffer, offset, length, null);
        if (bytesRead === 0) {
            return (0, exports.unixRead)({ binding, buffer, offset, length, fsReadAsync });
        }
        logger('Finished read', bytesRead, 'bytes');
        return { bytesRead, buffer };
    }
    catch (err) {
        logger('read error', err);
     

Stack trace:
image

@hspaay
Copy link

hspaay commented Nov 26, 2023

This might be related to Issue #2043

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

4 participants