1

I am using a named pipe as described in this post to run a command on the host from within a docker container.

To write to the named pipe from my node.js app (running in the container), I'm using the following:

const ws = fs.createWriteStream(`/path/to/pipe/in/container`);
const timeoutMs = 5000;
let finished = false;
ws.on('finish', () => {
    logger.info('finished writing command to mypipe');
    finished = true;
});
setTimeout(() => {
    if (!finished) {
        logger.warn('writing to mypipe timed out... restart pipe on host with:');
        logger.warn('# ~/execpipe &');
    }
}, timeoutMs);
ws.write(cmd);
ws.close();

I'm trying to account for the fact that sometimes the process which is reading content from the pipe (PART 3 in the linked post above) may have terminated, or may have not been started in the first place. If that process is not running, then writing to the pipe just seems to wait patiently forever, so I've put in a timeout of sorts.

But what I want to avoid is all of these writes backing up and all being run together, as soon as the process (to read content from the pipe) is restarted.

So in my timeout function what I really want to do is "cancel" the write, so that it never happens even when the content-reading process restarts, rather than simply warning about it.

How might this be achieved?

drmrbrewer
  • 11,491
  • 21
  • 85
  • 181
  • A named pipe isnt something that takes time to "boot" and then "runs". It also cant "terminate". Either it exists or it doesnt. A write to a pipe will block until something on the other end reads from the pipe. – The Fool Mar 06 '23 at 09:39
  • @TheFool sure, so if I determine that there is nothing on the other end within 5 secs, how do I stop the write to pipe so that it doesn't complete as soon as there *is* something on the other end? – drmrbrewer Mar 06 '23 at 09:43
  • I am not sure how to do that in nodejs. I am also not entirely sure what you want to do. You can try to close the write stream in your timeout function. Although I can image that the timeout thing you are trying to do has a race condition. – The Fool Mar 06 '23 at 09:53
  • I already tried `ws.close()` in the timeout function but it doesn't prevent the content being delivered to the pipe when it does eventually come into existence. Indeed, there is already a `ws.close()` right after `ws.write(cmd)`. What I want is to "pull back" the content which is waiting to be written to the pipe, so that it is not written when the pipe materialises. Maybe the better thing to do would be to check if the pipe exists first, before trying to write anything to it. – drmrbrewer Mar 06 '23 at 10:02
  • I think if the pipe doesnt exist you would get an error when trying to create the write stream. Thats what I mean when I say, its either there or not, and afterwards it depends on if something is reading. – The Fool Mar 06 '23 at 10:04
  • Also the close after the write is probable not run until the write is done. So if its blocking because no one is reading, the close is not executed. – The Fool Mar 06 '23 at 10:06
  • But as you describe it, it sounds like nodejs is buffering the write content. so the write itself is not blocked?! – The Fool Mar 06 '23 at 10:07
  • OK thanks, I'll give it some more thought before clarifying further if necessary. – drmrbrewer Mar 06 '23 at 10:08
  • Perhaps if you use a fille object directly instead of the stream. i.e. https://nodejs.org/api/fs.html#class-filehandle – The Fool Mar 06 '23 at 10:09
  • To clarify, the named pipe itself exists, and always exists (created in PART 1 of the linked post in my OP). The issue I'm really trying to address is when the process which is reading content sent to the pipe (PART 3 in the linked post) is killed (or has not yet been started). In that case, I'd like any content sent to the pipe to be "cleared out" so that it isn't handled when the process (to read from the pipe) is restarted. – drmrbrewer Mar 06 '23 at 10:34

0 Answers0