-
Notifications
You must be signed in to change notification settings - Fork 29.8k
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
support for polling linux character device for incoming data #9285
Comments
Does |
@mscdex |
@mbroadst What do you mean by "once it reads all the data?" I was thinking the |
@mscdex ah, yeah sorry I should be more clear. Given the following code snippet:
If there is no data currently available in the device the script immediately exits. If there is data it consumes the data, prints it, and exits again. It does not continue to watch the file for further changes. (I actually used that stream's implementation to model my own which continuously retries the |
So I asume you see an |
Yes, however that doesn't help all that much if you were perhaps thinking of using that to kick off a new stream - I basically end up with the same solution of constantly polling the device, rather than acting upon a notification that new data is available (something epoll will do for me) |
Does the |
@mscdex hm yes surprisingly it does seem to work, though I wouldn't have expected it to because this isn't in fact a serial port. In fact, all that would be needed would be their serialport_poller it looks like.
Whoa, not really sure where I got the idea that there was resistance 😄 Rather it looks like work is needed in libuv to provide the ioctl support needed. I still wonder if there might be interest in getting the generic access to polling. |
Serial ports are one of the original character devices. I think there is a way to do this, by opening a fd on the device with fs.open, then creating a net.socket using that fd, which may be undocumented, I can't recall how to do it off the top of my head, but its necessary when fds are passed across ipc channels, there is a way. cdevs look more like sockets than like files, which is why the fs stream things don't work. The serialport module would probably be more robust. |
@sam-github right. However, while serial ports are character devices, not all character devices are serial ports. I forgot to mention that I had indeed tried your approach as well to no avail:
results in:
There doesn't appear to be any way to tap into this from the user side either, as the handle type is coming from I don't necessarily agree that the serialport module would be more robust, as it's wildly overweight for my particular use case (I'm clocking in at ~11M right now for |
If you are comfortable using unstable and undocumented APIs, you can create the handle like this: const fd = /* ... */;
const Pipe = process.binding('pipe_wrap').Pipe;
const handle = new Pipe();
handle.open(fd);
const socket = new net.Socket({ handle }); Note that passing a file descriptor that is not compatible with epoll will almost certainly abort the process. Everything from process.binding is unstable by definition so use at your own peril.
There is nothing stopping you from writing a small C++ add-on that does that but as I mentioned, libuv will simply abort when the file descriptor is incompatible. That's why |
a) I've never understood the tendency to avoid using a library because it has too many features and is "too mature", so unless you literally are on a resource constrained system and can't afford the disk space, that 11 meg is irrelevant. Except in this case... |
@bnoordhuis ah, I didn't know I had access to the internal bindings that way - thank you, I'll give that a shot. @sam-github I should clarify that I'm not opposed to using the I have no issues creating my own custom module to do this in a far more compact fashion than |
@bnoordhuis it doesn't look like update: as far as I can tell grepping through the source, none of the wraps provide direct access to |
It sounds like what you need is a small add-on that wraps uv_poll_t. It shouldn't be hard to write and I expect one or more already exist. |
@bnoordhuis yes that's correct, in fact the purpose of this issue was to determine if adding such functionality to node directly would be welcomed |
a) I've never understood the tendency to avoid using a library because it has more than the exact feature set need at this moment, so unless you literally are on a resource constrained system and can't afford the disk space, that 11 meg is irrelevant, and also easily removable. b) 7+ meg of that is node-pre-gyp, which mostly exists to support windows users by downloading precompiled binaries for them, and has zero run-time cost, its just run by the npm install script before building the addon. I wouldn't say using node-pre-gyp makes a node addon "overweight", but that's your call, and its trivially strippable from the serialport module if you fork it, or commit serialport as a dep ("vendor" it). |
@sam-github are you just trying to reiterate your point here, or was that accidentally sent again? |
That was definitely an accident! Don't know what happened there, it looked unsent, sorry. |
Has there been any update on this feature request? I've done some research and it looks like the situation hasn't changed. |
Seems to me like the consensus of the project Collaborators involved in this discussion is that this is better suited for an add-on/third-party module than for core. I'm going to close this at this time. If I've misunderstood or if you otherwise believe that closing this is the wrong thing to do, please comment or (if GitHub allows you to do so) re-open. Thanks! |
v6.9.1
Linux T40001 3.13.0-63-generic Deprecate fs.exists or fix its API #103-Ubuntu SMP Fri Aug 14 21:42:59 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
fs, net
Hi, I'm trying to determine whether it's possible to poll a linux character device using node.js, and where exactly the breakdown occurs between libuv and node. I'm putting together a small experimental qemu agent which currently requires communicating over a virtio-serial provided character device, and as far as I have tried it doesn't seem possible presently to monitor that fd through any means provided to me in node.
As a first step I just wanted to check if it might be a limitation of epoll, so I took a modified version of this code, compiled it and listened to the device for incoming data, and was able to verify that epoll in fact notified on change.
I've tried the following methods:
fs.watch
- this doesn't throw any errors, but simply never emits achange
event on incoming data.net.createConnection
- this throws aECONNREFUSED
as expected, since this is not a sockettty.ReadStream
- also fails because of course this isn't a TTYMy only remaining option has been to simply poll every
Nms
usingfs.read
orfs.readFile
within a class duck typed as anet.Socket
, which is less than ideal. I thought I might just get away with thefs.watch
approach, but from perusing the source code it looks like that is bound to auv_fs_event_start
which is probably falling back to inotify in this case.So three questions occur to me at this point:
fs
,net
,os
, something else?Thanks!
The text was updated successfully, but these errors were encountered: