Code Monkey home page Code Monkey logo

node-subprocess-stderr's Introduction

NodeJS subprocess stderr backpressure demo

This quick demo stack provides a minimal example of the streams backpressure issue with the stderr stream of a child process spawned in NodeJS.

Plain description of the problem

Suppose that a NodeJS application spawns one or more C-based applications as child processes using the child_process.spawn() method. These child processes write data to stderr using the fprintf(stderr) method.

If the NodeJS application does not bind a listener to the child.stderr.on('data') event, the contents of stderr will be buffered until they reach a maximum amount known as the high watermark level. Since the stderr is represented as a stream on the NodeJS side, this behaviour is inherited from the streams API. In Node v20 at least, the default for this is 16kb.

In C apps using the fprintf method (but likely in many other stderr implementations across programming languages), once that stream buffer is full, no more contents can be written to stderr. Consequently, the app will block at the stderr write that exhausted the parent Node app's buffer. In essence, after writing 16kb of data, the child app hangs (blocks) indefinitely, "waiting" for a buffer flush which will never occur.

Solution

The solution is to simply bind an event handler to stderr such as:

    child.stderr.on('data', (data) => {
        console.log(`Received from stderr: ${data}`);
    });

Now the data is being 'handled' and won't accumulate. The child process can continuously push data to stderr without issues.

Demo (of the problem)

First, compile the C app running gcc writer.c -o writer. Next, launch the node app using node app.js. This action causes Node to start the C writer as a child process. The C writer will write to both stderr and to a file. stderr will eventually block once the Node buffer is full. Since a write is done to a log file each time after a successful stderr write, you can see "how far along" the writes got by tailing the ./logs/log.txt file (tail logs/log.txt in a new Terminal window).

On my machine configuration, the app will reach no more than 735 iterations before blocking indefinitely, since the data size of those 735 iterations is enough to fill the default buffer.

Demo (of the solution)

Compile the C app if you haven't done so already, and then run the node app with: node app.js --bind-stderr. This will cause the Node app to add an appropriate event listener to the stderr stream of the child process, thus preventing the silent buffering of that stderr activity and the eventual blocking when that buffer becomes full.

When running in this configuration, your NodeJS will print the stderr being provided by the C app and it should run indefinitely without ever blocking, going well beyond the 735 iterations from before when there was no event handler attached:

Received from stderr: [1699165458] [14308] Wrote to stderr.

node-subprocess-stderr's People

Contributors

tarek58 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.