Skip to content
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

Stdin support causing possible regression in 3.6.0 #147

Closed
voxpelli opened this issue Jun 22, 2018 · 11 comments
Closed

Stdin support causing possible regression in 3.6.0 #147

voxpelli opened this issue Jun 22, 2018 · 11 comments

Comments

@voxpelli
Copy link

It looks like we are sometimes struck by a regression in 3.6.0, probably caused by #128, where we probably have been running concurrently in a place where it has received data on stdin, data that it has previously ignored.

That data seems to now be parsed, looking for : characters, and if one is found it's expected to be the position or name of the process to forward that input to and otherwise it's forwarded to the default process.

Previously none of that happened – no forwarding of stdin and no parsing of the stdin data. Forwarding such data as a default could therefore be considered a breaking change that requires a new major version and if released as a minor version, as now, it needs to be put behind a flag (like --forward-stdin).

Now that it has been released the most important thing is to make it work though.

I see two issues that needs fixing:

  1. There's an exception that we're sometimes encountering:
TypeError: Cannot read property 'write' of null
    at Socket.process.stdin.on (<project-path>/node_modules/concurrently/src/main.js:306:26)
    at Socket.emit (events.js:180:13)
    at addChunk (_stream_readable.js:274:12)
    at readableAddChunk (_stream_readable.js:261:11)
    at Socket.Readable.push (_stream_readable.js:218:10)
    at Pipe.onread (net.js:581:20)

This could be silenced by changing if (target) { to if (target && target.stdin) { on line 306in:

https://github.com/kimmobrunfeldt/concurrently/blob/b4574e1b76a86410ad2b7cb14ae8f0c6c3a314b3/src/main.js#L304-L309

  1. Forwarding stdin by default to the first process and, in the case of :-characters in the stdin, to whatever that resolves to, can break current setups and should either an opt-in or an opt-out so that one can easily fix setups that were working before, but isn't working now.
@wintercounter
Copy link

wintercounter commented Jun 26, 2018

Same issue here. I have to explicit define --default-input-target to work at least for the default one.

EDIT

I logged out target and here is what I get:

ChildProcess {
  _events:
   { close: [Function: innerHandler],
     error: [Function: innerHandler] },
  _eventsCount: 2,
  _maxListeners: undefined,
  _closesNeeded: 1,
  _closesGot: 0,
  connected: false,
  signalCode: null,
  exitCode: null,
  killed: false,
  spawnfile: 'cmd.exe',
  _handle: Process { owner: [Circular], onexit: [Function], pid: 25712 },
  spawnargs:
   [ 'cmd.exe',
     '/s',
     '/c',
     '"node C:\\......\\node_modules\\jest-cli\\bin\\jest.js -o --watch --passWithNoTests --config=C:\\......\\config\\jest\\index.js"' ],
  pid: 25712,
  stdin: null,
  stdout: null,
  stderr: null,
  stdio: [ null, null, null ] }

I have a feeling that jest is causing the issue here somehow.

EDIT 2

I think my case is not related to the original topic even tho it's the same error. I think my issue is that I'm running concurrently with spawn.

spawn('node', [
	path.resolve(__dirname, 'node_modules/concurrently/src/main.js'),
	'-k',
	'-n',
	Object.keys(eco).join(','),
	...Object.values(eco).map(({command}) => `"${command.join(' ')}"`),
	'-r',
	'--default-input-target',
	Object.keys(eco)[0]
], { shell: true, stdio: 'inherit' })

See https://stackoverflow.com/questions/27786228/node-child-process-spawn-stdout-returning-as-null

I think it's the same issue. Should I open a new issue for this? Any idea for a workaround?

@gustavohenke
Copy link
Member

gustavohenke commented Jun 27, 2018

Hey folks,
I'm so sorry for the oversight on detecting these kinds of problems! It should really have been a major release.

@voxpelli: you seem to have some good context of the problem, are you up for fixing this? I might not be so free any time soon.

@wintercounter: So processes spawned by concurrently are likely inheriting the I/O from the parent... so your fix could be as easy as changing the stdio option of your spawn call (note the emphasis).

@voxpelli
Copy link
Author

@gustavohenke Sure, I can try to find some time for it. Which of the mentioned solution would you prefer? A new opt-out for stdin or changing it to an opt-in?

@wintercounter
Copy link

wintercounter commented Jun 27, 2018

@gustavohenke I tried every possible combo, even tried to tweak concurrently's main.js, couldn't make it work. Stdin is either null or no output otherwise. Concurrently is spawing the process with inherit in raw mode (which is essential for most of the things I'm trying to use here) and from that point it cannot write to stdin on it's own. Docs should be updated to reflect that using -r will disable input forward and as @voxpelli stated, condition should be added to prevent errors.

Maybe with -r it would be possible to simply not have any custom code to handle commands but simply rely on node, inherint stdio and each process would get the input. Again, -r would completely disable that feature as it cannot work with it anyway.

EDIT
I have tested the above. I have webpack-serve and jest running alongside. Jest's output is fully swallowed while webpack's output appears fine.

EDIT 2
I managed to get output work but after first input everything acts like it's being completely frozen :S I can only close the terminal, CTRL+C doesn't work either. Oh well, i guess my cases are too much of an edge case to be address for a fix.

EDIT 3
Created a repo to test Jest. These are the only settings (simply inherit) that will correctly pass output. However after first input it dies. https://github.com/wintercounter/concurrently-jest-test

npm install
npm test

Please note I'm testing this on Windows 10

EDIT 4
I've tested on Mac, same issue.

I also added npm run test-concurrently-cli and npm run test-jest-cli
First one fails, last one runs fine. Seems like it's not related to spawning concurrently manually, issues with input are there even if I run concurrently from CLI.

(Sry for edits, I don't want to spam ur inbox).

EDIT 5
Investigation ended. See jestjs/jest#5017

@wintercounter
Copy link

@voxpelli Just to have something topic related here :)

if (target) {
    if (target.stdin) {
        // write
    }
}

With target && target.stdin it'll still log error when it shouldn't.

@gustavohenke
Copy link
Member

Wow, nice investigation skills @wintercounter! Thanks for looking so deeply into this 😀

@voxpelli let's make it an opt-in, then I will cut a new major release, so that we don't get 2 breaking changes in a row...

@voxpelli
Copy link
Author

I'll try to look at it asap after my deadline today 👍

@hyperknot
Copy link

I'm having problems with target.stdin.write(line): Cannot read property 'write' of null as well on 3.6.1. What was the latest stable version without this problem?

@gustavohenke
Copy link
Member

gustavohenke commented Aug 22, 2018

v3.5.0 had no support for stdin, if that's fine for you @hyperknot 🙂

@hyperknot
Copy link

Thanks, 3.5.x works perfectly.

@gustavohenke
Copy link
Member

Hiya folks! v4.0.0 is out with a breaking change relating to this! 🚢
You know have to specify --handle-input in order to opt into the input handling feature.

robdodson referenced this issue in WICG/focus-visible Aug 28, 2018

## Version **4.0.0** of **concurrently** was just published.

<table>
  <tr>
    <th align=left>
      Dependency
    </th>
    <td>
      <a target=_blank href=https://github.com/kimmobrunfeldt/concurrently>concurrently</a>
    </td>
  </tr>
  <tr>
      <th align=left>
       Current Version
      </th>
      <td>
        3.6.1
      </td>
    </tr>
  <tr>
    <th align=left>
      Type
    </th>
    <td>
      devDependency
    </td>
  </tr>
</table>



The version **4.0.0** is **not covered** by your **current version range**.

If you don’t accept this pull request, your project will work just like it did before. However, you might be missing out on a bunch of new features, fixes and/or performance improvements from the dependency update.

It might be worth looking into these changes and trying to get this project onto the latest version of concurrently.

If you have a solid test suite and good coverage, a passing build is a strong indicator that you can take advantage of these changes directly by merging the proposed change into your project. If the build fails or you don’t have such unconditional trust in your tests, this branch is a great starting point for you to work on the update.


---


<details>
<summary>Release Notes</summary>
<strong>v4.0.0</strong>

<p>More than anything, v4 is just a big refactor to allow changes to be made faster and more reliably.<br>
It does feature some small breaking changes, and maybe even fixes some longstanding bugs.</p>
<h2>Breaking changes</h2>
<ul>
<li><strong>The CLI option <code>--allow-restarts</code> is no more.</strong><br>
Instead, just set <code>--restart-tries</code> to something greater than <code>0</code>.</li>
<li><strong>Input handling is now opt-in via <code>--handle-input</code> flag.</strong> (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="334862875" data-permission-text="Issue title is private" data-url="https://github.com/kimmobrunfeldt/concurrently/issues/147" href="https://urls.greenkeeper.io/kimmobrunfeldt/concurrently/issues/147">#147</a>)<br>
It does come with some specific input parsing that would make it difficult for you to use it.</li>
<li><strong>Setting prefix to <code>none</code> will now actually not prefix commands' outputs.</strong><br>
Previously, it would prefix with <code>[]</code>.</li>
<li><strong><code>SIGINT</code>s/<kbd>Ctrl</kbd>+<kbd>C</kbd> will now be handled gracefully.</strong> (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="341012242" data-permission-text="Issue title is private" data-url="https://github.com/kimmobrunfeldt/concurrently/issues/150" href="https://urls.greenkeeper.io/kimmobrunfeldt/concurrently/issues/150">#150</a>)<br>
No more exiting with code <code>1</code> or tweaking <code>--success</code> flag.</li>
</ul>
<h2>No more <code>null</code> exit codes (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="298319293" data-permission-text="Issue title is private" data-url="https://github.com/kimmobrunfeldt/concurrently/issues/133" href="https://urls.greenkeeper.io/kimmobrunfeldt/concurrently/issues/133">#133</a>)</h2>
<p>That's a pretty bad bug that existed till now. You won't see a log like this anymore:</p>
<pre><code>[1] npm run lint-watch exited with code null
</code></pre>
<p>What you will see going forward is the <strong>actual exit signal</strong>:</p>
<pre><code>[1] npm run lint-watch exited with code SIGTERM
</code></pre>
<h2>concurrently finally gets a shiny <g-emoji class="g-emoji" alias="sparkles" fallback-src="https://assets-cdn.github.com/images/icons/emoji/unicode/2728.png">✨</g-emoji> programmatic API!</h2>
<p>Closes <a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="218521066" data-permission-text="Issue title is private" data-url="https://github.com/kimmobrunfeldt/concurrently/issues/101" href="https://urls.greenkeeper.io/kimmobrunfeldt/concurrently/issues/101">#101</a>, <a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="239304263" data-permission-text="Issue title is private" data-url="https://github.com/kimmobrunfeldt/concurrently/issues/112" href="https://urls.greenkeeper.io/kimmobrunfeldt/concurrently/pull/112">#112</a>. Maybe even <a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="222040304" data-permission-text="Issue title is private" data-url="https://github.com/kimmobrunfeldt/concurrently/issues/103" href="https://urls.greenkeeper.io/kimmobrunfeldt/concurrently/issues/103">#103</a>.</p>
<div class="highlight highlight-source-js"><pre><span class="pl-k">const</span> <span class="pl-c1">concurrently</span> <span class="pl-k">=</span> <span class="pl-c1">require</span>(<span class="pl-s"><span class="pl-pds">'</span>concurrently<span class="pl-pds">'</span></span>);
<span class="pl-k">await</span> <span class="pl-en">concurrently</span>([
	<span class="pl-s"><span class="pl-pds">'</span>npm:watch-*<span class="pl-pds">'</span></span>,
	{ name<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>server<span class="pl-pds">'</span></span>, command<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>nodemon<span class="pl-pds">'</span></span> }
], {
  prefix<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>name<span class="pl-pds">'</span></span>,
  killOthers<span class="pl-k">:</span> [<span class="pl-s"><span class="pl-pds">'</span>failure<span class="pl-pds">'</span></span>],
  restartTries<span class="pl-k">:</span> <span class="pl-c1">3</span>
});</pre></div>
<p>Check the docs <a href="https://urls.greenkeeper.io/kimmobrunfeldt/concurrently/blob/v4.0.0/README.md#programmatic-usage">here</a> for some info on how to use it.</p>
</details>

<details>
<summary>Commits</summary>
<p>The new version differs by 28 commits.</p>
<ul>
<li><a href="https://urls.greenkeeper.io/kimmobrunfeldt/concurrently/commit/3690676886510e37ede19d1ce1494f0064d898b1"><code>3690676</code></a> <code>4.0.0</code></li>
<li><a href="https://urls.greenkeeper.io/kimmobrunfeldt/concurrently/commit/b4e414caff5b55e55c47932d8b8b041b29fae99a"><code>b4e414c</code></a> <code>npm: update and remove some deps</code></li>
<li><a href="https://urls.greenkeeper.io/kimmobrunfeldt/concurrently/commit/4043fc2387893031a83c598a464114c8caa04849"><code>4043fc2</code></a> <code>Exit gracefully on SIGINT (#164)</code></li>
<li><a href="https://urls.greenkeeper.io/kimmobrunfeldt/concurrently/commit/b1daf8dd4670b1f64221dc2fe3feeb3bd904e7aa"><code>b1daf8d</code></a> <code>logger: show no prefix when the format is none</code></li>
<li><a href="https://urls.greenkeeper.io/kimmobrunfeldt/concurrently/commit/58d7d97b99deff73638ecc0959f74721877cd682"><code>58d7d97</code></a> <code>Take options such as prefixLength and outputStream</code></li>
<li><a href="https://urls.greenkeeper.io/kimmobrunfeldt/concurrently/commit/1d0598a3281cd34744187b6bbb5c724a30707f0b"><code>1d0598a</code></a> <code>docs: add programmatic API usage</code></li>
<li><a href="https://urls.greenkeeper.io/kimmobrunfeldt/concurrently/commit/571671bf11bf4baaabc101e3c4cfdc35f692c4d6"><code>571671b</code></a> <code>Add missing export of LogExit</code></li>
<li><a href="https://urls.greenkeeper.io/kimmobrunfeldt/concurrently/commit/7ac9b6eb6187d5ff45bcaaa79e4eacd6993777ad"><code>7ac9b6e</code></a> <code>Remove unused RxJS schedulers</code></li>
<li><a href="https://urls.greenkeeper.io/kimmobrunfeldt/concurrently/commit/caa23b32686636a13b4d55b1f6530dbc1876fd45"><code>caa23b3</code></a> <code>bin: change tested exit code to 1 on Windows (#163)</code></li>
<li><a href="https://urls.greenkeeper.io/kimmobrunfeldt/concurrently/commit/bfd7501032811247e2997898d5203bbb5dafa75b"><code>bfd7501</code></a> <code>ci: run AppVeyor on Node 10</code></li>
<li><a href="https://urls.greenkeeper.io/kimmobrunfeldt/concurrently/commit/adcc0b5494a404d83ca2a922e4dec09a9905a168"><code>adcc0b5</code></a> <code>Merge pull request #157 from kimmobrunfeldt/v4</code></li>
<li><a href="https://urls.greenkeeper.io/kimmobrunfeldt/concurrently/commit/0e60d2d6faa6eeb2cb5de07662244b3171b8b0fc"><code>0e60d2d</code></a> <code>docs: move the why section to the top</code></li>
<li><a href="https://urls.greenkeeper.io/kimmobrunfeldt/concurrently/commit/b1361832e8560756f9d273ba76c144801dc7a794"><code>b136183</code></a> <code>docs: update help section</code></li>
<li><a href="https://urls.greenkeeper.io/kimmobrunfeldt/concurrently/commit/c127d92a0e920769ab885acdbd774a0f47e146b7"><code>c127d92</code></a> <code>Add support for prefix length (#162)</code></li>
<li><a href="https://urls.greenkeeper.io/kimmobrunfeldt/concurrently/commit/daddad1ad329851443cbd812a890f9ce02bab8df"><code>daddad1</code></a> <code>bin: don't check order of lines emitted</code></li>
</ul>
<p>There are 28 commits in total.</p>
<p>See the <a href="https://urls.greenkeeper.io/kimmobrunfeldt/concurrently/compare/ba6f25a6c190b321de86e39c73b38d74ec403f01...3690676886510e37ede19d1ce1494f0064d898b1">full diff</a></p>
</details>

<details>
  <summary>FAQ and help</summary>

  There is a collection of [frequently asked questions](https://greenkeeper.io/faq.html). If those don’t help, you can always [ask the humans behind Greenkeeper](https://github.com/greenkeeperio/greenkeeper/issues/new).
</details>

---


Your [Greenkeeper](https://greenkeeper.io) bot 🌴
mdhitchcock referenced this issue in mdhitchcock/nps-utils Sep 26, 2019
… 3.6.1 and to more current ^4.1

The version of concurrently that the current package.json locks in is old and has a couple serious
bugs (https://github.com/kimmobrunfeldt/concurrently/issues/147 and
https://github.com/kimmobrunfeldt/concurrently/issues/193). One effect is that any keystroke in a
terminal running a package script using nps-utils will crash and leave processes running. This
change is just to bump the version of concurrently from ^3.4.0 (which will install 3.6.1) to version
^4.1.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants