title: CPU-bound process blocks worker pool while using Child Process in NestJS HTTP server
body: <p><strong>Node version:</strong> v10.13.0</p>
  <p>I'm trying a very simple test on NodeJS request concurrency involving heavy CPU-calculation. I understand NodeJS is not the best tool for CPU-bound processes, and that a child process should not be spawned <em>systematically</em>, but this code is for the sake of testing how the child process works. Also this is written in TypeScript, using NestJS.</p>
  <p><strong>src/app.controller.ts</strong></p>
  <pre><code>import { Get, Param, Controller } from '@nestjs/common';
  import fork = require('child_process');
  
  @Controller()
  export class AppController {
    @Get()
    async root(): Promise&lt;string&gt; {
      let promise = new Promise&lt;string&gt;(
          (resolve, reject) =&gt; {
            // spawn new child process
            const process = fork.fork('./src/cpu-intensive.ts');
            process.on('message', (message) =&gt; {
              // when process finished, resolve
              resolve( message.result);
            });
            process.send({});    
          }
      );    
      return await promise;
    }
  }
  </code></pre>
  <p><strong>src/cpu-intensive.ts</strong></p>
  <pre><code>process.on('message', async (message) =&gt; {
    // simulates a 10s-long process
    let now = new Date().getTime();
    let waittime = 10000; // 10 seconds
    while (new Date().getTime() &lt; now + waittime) { /* do nothing */ };
    // send response to master process
    process.send({ result: 'Process ended' });
  });
  </code></pre>
  <p>Such a long process, <strong>if executed without spawning</strong> new child processes, leads to this timeline of results, with 5 concurrent requests (noted from #1 to #5). Each process blocking the loop-event, each request has to wait for the previous ones to complete to be answered.</p>
  <pre><code>Time 0    10   20   30   40   50
  #1   +----+
  #2   +----+----+
  #3   +----+----+----+
  #4   +----+----+----+----+
  #5   +----+----+----+----+----+
  </code></pre>
  <p><strong>While spawning new child processes</strong>, I was <strong>expecting</strong> each process would be handled concurrently by a different logical core on my CPU (mine has 8 logical cores), leading to this predicted timeline:</p>
  <pre><code>Time 0    10   20   30   40   50
  #1   +----+
  #2   +----+
  #3   +----+
  #4   +----+
  #5   +----+
  </code></pre>
  <p>Though, <strong>I observe this strange result</strong> on each test:</p>
  <pre><code>Time 0    10   20   30   40   50
  #1   +----+
  #2   +----+----+
  #3   +----+----+----+
  #4   +----+----+----++
  #5   +----+----+----+-+
  </code></pre>
  <p>The first 3 requests act as if the worker pool was starved, though I'd assume that 3 different pools would have been created. The 2 last requests are very confusing, as they act like working concurrently with request #3.</p>
  <p>I'm currently looking for an explanation for:</p>
  <ul>
  <li>why the first 3 requests don't act as if running concurrently</li>
  <li>why the last 3 requests act as if running concurrently</li>
  </ul>
  <hr />
  <p>Please note that if I add another 'fast' method as follows:</p>
  <pre><code>  @Get('fast')
    async fast(): Promise&lt;string&gt; {
      return 'Fast process ended.';
    }
  </code></pre>
  <p>this method is not impacted by the CPU-intensive processes run in concurrency, and replies always instantly.</p>