Skip to content

Instantly share code, notes, and snippets.

@jichu4n
Last active April 12, 2024 04:05
Show Gist options
  • Save jichu4n/b654ef675a0beb87ac3349b0f1babaf8 to your computer and use it in GitHub Desktop.
Save jichu4n/b654ef675a0beb87ac3349b0f1babaf8 to your computer and use it in GitHub Desktop.
Repro for SerialPort issue where Node does not exit after close() in flowing mode
$ ./node_modules/.bin/ts-node src/serialport-test.ts
serialport/stream opening path: /dev/ttyUSB0 +0ms
serialport/bindings-cpp open +0ms
serialport/bindings-cpp/poller Creating poller +0ms
serialport/stream opened path: /dev/ttyUSB0 +25ms
serialport-test opened +0ms
serialport/stream _read reading { start: 0, toRead: 65536 } +1ms
serialport/bindings-cpp read +24ms
serialport/bindings-cpp/unixRead Starting read +0ms
serialport-test closing +3s
serialport/stream #close +3s
serialport/bindings-cpp close +3s
serialport/bindings-cpp/poller Stopping poller +3s
serialport/bindings-cpp/poller Destroying poller +0ms
serialport/stream binding.close finished +1ms
serialport-test closed +2ms
There are 2 handle(s) keeping the process running
# Timeout
node:internal/async_hooks:202
node:internal/async_hooks:504
node:internal/timers:164
node:internal/timers:198
/home/chuan/Projects/palm-sync/src/serialport-test.ts:91
node:internal/modules/cjs/loader:1256
/home/chuan/Projects/palm-sync/node_modules/ts-node/dist/index.js:857 - return _compile.call(this, result, fileName);
node:internal/modules/cjs/loader:1310
# FSREQCALLBACK
node:internal/async_hooks:202
node:internal/util:375
node:internal/util:361
/home/chuan/Projects/palm-sync/node_modules/@serialport/bindings-cpp/dist/unix-read.js:27 - const { bytesRead } = await fsReadAsync(binding.fd, buffer, offset, length, null);
/home/chuan/Projects/palm-sync/node_modules/@serialport/bindings-cpp/dist/linux.js:77 - return (0, unix_read_1.unixRead)({ binding: this, buffer, offset, length });
/home/chuan/Projects/palm-sync/node_modules/@serialport/stream/dist/index.js:199 - this.port.read(pool, start, toRead).then(({ bytesRead }) => {
node:internal/streams/readable:507
^C
import debug from 'debug';
import {SerialPort} from 'serialport';
import whyIsNodeRunning from 'why-is-node-running';
const log = debug('serialport-test');
async function run() {
// Open serial port
const sp = new SerialPort({
path: '/dev/ttyUSB0',
baudRate: 115200,
autoOpen: false,
});
await new Promise<void>((resolve, reject) =>
sp.open((err) => (err ? reject(err) : resolve()))
);
log('opened');
// Attach data event listener.
sp.on('data', (data) => {
log(`data: ${data.toString()}`);
});
// Wait 3 seconds.
await new Promise<void>((resolve) => setTimeout(resolve, 3000));
// Close serial port.
log('closing');
sp.pause(); // same result with or without
await new Promise<void>((resolve, reject) =>
sp.close((err) => (err ? reject(err) : resolve()))
);
sp.destroy(); // same result with or without
log('closed');
}
if (require.main === module) {
debug.enable('*');
run();
// See why is Node not terminating after 5 seconds.
setTimeout(whyIsNodeRunning, 5000);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment