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

'drain' event is not being emitted, hanging process #4

Closed
chrisgladd opened this issue Nov 25, 2013 · 35 comments
Closed

'drain' event is not being emitted, hanging process #4

chrisgladd opened this issue Nov 25, 2013 · 35 comments

Comments

@chrisgladd
Copy link
Contributor

The only place I've run into this issue is in a grunt (0.4.2) task running on my TeamCity server (a windows machine) so it may have something to do with the process.on('exit') fix not being called.

From what I can gather about the 'drain' event, I don't believe it's fired unless the stream has broken the stream._writableState.highWaterMark. So if the stream.bufferLength is not zero, but the highWaterMark hasn't been crossed, the 'drain' event will not be emitted and the process will never exit.

if (stream.bufferSize === 0) {
with
if (!stream._writableState.needDrain) {

Seems to solve the issue for me and still preserve the task output but I'm not sure that's 100% correct either.

@EvgenyGusev
Copy link

+1
I have the same problem. In Teamcity grunt tasks not exit properly (hanging). I tried to change to

if (!stream._writableState.needDrain) { 

and it worked!

@cowboy
Copy link
Owner

cowboy commented Nov 25, 2013

I'd love for someone who knows more about Node.js streams than me to take a look at this as well. /cc @shama @vladikoff @tbranyen you guys have any opinions on this?

@Bartvds
Copy link

Bartvds commented Nov 25, 2013

I have a vague problem with hanging processes on Windows that I can solve with the same change to node-exit as @chrisgladd and @EvgenyGusev mentioned:

if (!stream._writableState.needDrain) {

I can 100% reproduce mine using local grunt-contrib-connect, but it only happens if I run grunt.cmd from grunt v0.4.2 as External Tool from WebStorm (JetBrains IntelliJ). Using my regular console or WebStorm's interactive Terminal all exit as expected. Using grunt v0.4.1 this does not hang either (but then we have the truncated output).

If I take the hanging version, go in the dependencies and change the node-exit line it exits as expected.

Original ticket: gruntjs/grunt-contrib-connect#59 (with isolated demo from earlier)

@alimfeld
Copy link

After upgrading to grunt 0.4.2 (with node-exit), time-grunt (https://github.com/sindresorhus/time-grunt) stops printing elapsed times. It seems like the function to print the statistics (registered on process 'exit') is not called anymore.

Also I get hanging node processes on Windows when calling grunt via the exec-maven plugin (http://mojo.codehaus.org/exec-maven-plugin/).

@cowboy
Copy link
Owner

cowboy commented Nov 25, 2013

@alimfeld can you check and see if the if (!stream._writableState.needDrain) { fix solves your problem?

@cowboy
Copy link
Owner

cowboy commented Nov 25, 2013

I'd love to fix this issue, but I need a PR for it that has been tested in Windows 7 and Windows 8, in cmd.exe, PowerShell and git-bash. I don't have access to all these combinations here, so I'm going to need some help.

Can anyone help with this?

@vladikoff
Copy link

@Bartvds so you mentioned a fix worked for you, could you test out time-grunt and grunt-karma (with a redirect command > )

@Bartvds
Copy link

Bartvds commented Nov 25, 2013

@vladikoff Sure, but it will take a moment to get a setup. I will get back with this asap.

@vladikoff
Copy link

@Bartvds thanks so much!

@Bartvds
Copy link

Bartvds commented Nov 25, 2013

@vladikoff Things are getting weirder by the minute:

time-grunt gives me no summaries on grunt 0.4.2 at all. Not even in plain cmd.exe console. On 0.4.1 it does. (I'm on Widows Vista 64 atm)

Neither does it when changing the line in node-exit.

My test code: https://github.com/Bartvds/demo-time-grunt-broken

This already breaks before I try redirecting.


Also I tried my earlier issue with grunt-contrib-connect from standard cmd.exe but with > redirect (to a file): and then it does exit as expected.

I'm no expert in CLI tricks like redirects, so what I did was just this (please confirm this is correct):

$ grunt test>foo.txt

It will run with no CLI output, exit and in foo.txt I will see the expected output.


Side info: from way back before node-exit, to run grunt (with the truncated output problems) as External Tool in WebStorm I also used some 'redirect-to-file-then-read-that-to-console' command to make grunt not truncate (took that from google somewhere):

grunt.cmd > %TEMP%\test & type %TEMP%\test & del %TEMP%\test

I mention this as maybe it sheds some light on what is going on (it is beyond me)

@Bartvds
Copy link

Bartvds commented Nov 25, 2013

In my last message I forgot to note this confirms @alimfeld 's report.

@alimfeld
Copy link

It seems to be the following line in node-exit that causes time-grunt to not output the statistics anymore:

    // Prevent further writing.
    stream.write = function() {};

I guess this breaks all functions that try to write something in a process 'exit' callback (e.g. time-grunt).

@cowboy I will check tomorrow (when I have access to my Windows machine), whether the if (!stream._writableState.needDrain) { fix solves the problem with hanging process and truncated output.

@Bartvds
Copy link

Bartvds commented Nov 25, 2013

@vladikoff I have a demo set for grunt-karma here

Used on standard console it exits as expected on for grunt 0.4.1 and 0.4.2.

But hangs on both when redirecting $ grunt test>foo.txt

I tried the possible fix but is was no good. 😢


(time for the customary referral to the origin of all this fun: nodejs/node-v0.x-archive#3584) 😞

@cowboy
Copy link
Owner

cowboy commented Nov 25, 2013

@Bartvds are you saying that the grunt-karma bug you're testing wasn't introduced in Grunt 0.4.2?

@Bartvds
Copy link

Bartvds commented Nov 25, 2013

@cowboy I can only say it seems like that is the case.

But I would like some confirmation on this before you build on it: this was not my original bug: maybe @stephen-styrchak-hbo who reported the grunt-karma issue can verify this.

(if it works for him I'm curious what the differences with my minimal demo would be)

@Bartvds
Copy link

Bartvds commented Nov 25, 2013

@cowboy I stripped down my demo even further, now it actually does exit in grunt 0.4.1 when I redirect using $ grunt test>foo.txt.

@vladikoff
Copy link

if (!stream._writableState.needDrain) { doesn't work for me in cmd.exe
It writes to file, full output, but hangs.

Works in PowerShell

@chrisgladd
Copy link
Contributor Author

I've added a pull request for this issue that writes an empty string to the stream and uses the callback to call tryToExit(). I tested it in Windows 7 & 8 in cmd, powershell, and git-bash as well as in the original issue w/ on my TeamCity server and it was functioning as expected in each case. It isn't pretty but seems to get the job done.

@vladikoff
Copy link

Hey @chrisgladd , testing it out. Will let you know how it goes

@Bartvds
Copy link

Bartvds commented Nov 26, 2013

@chrisgladd I've tested this for my cases (Windows Vista 64):

node-exit's own tests in the drain-fix branch all pass.

The fix solved my original grunt-contrib-connect issue (grunt now exits as expected in embedded WebStorm External Tool).

The last grunt-karma test also exits as expected when using $grunt test>foo.txt (in cmd.exe).

Only thing remaining broken is time-grunt: I still get no report (but if I have to choose I'd rather have properly exiting processes then timing reports :)

@vladikoff
Copy link

The fix also works for me in cmd and powershell.

@Bartvds I noticed time-grunt uses process.exit, it might need to be fixed in time-grunt itself.

// cc @cowboy @sindresorhus

@vladikoff
Copy link

I think we also know that using process.exit alone will never work with output redirection on Windows.

@sindresorhus
Copy link

@vladikoff how do you suggest I do that?

I'm just using the Node process exit event:

Emitted when the process is about to exit. This is a good hook to perform constant time checks of the module's state (like for unit tests). The main event loop will no longer be run after the 'exit' callback finishes, so timers may not be scheduled.

@alimfeld
Copy link

Trying to summarize I think we have three issues we're discussing here:

  1. Hanging process on Windows when redirecting (bug in node-exit)
  2. Truncated output (that's actually what node-exit tries to solve)
  3. Writes are prevented after using exit causing e.g. time-grunt to not work anymore (bug/feature?)

Back on my Windows (7) machine I tried the following (in PowerShell, cmd and git bash):

However, as stated above I'm not sure, whether preventing further writes is actually a bug or a feature...

@alimfeld
Copy link

I added a pull request modifying #5 to not prevent further writing: #6.

@vladikoff
Copy link

@alimfeld does output redirection work for you with your changes?

@alimfeld
Copy link

@vladikoff Output redirection works. However, I don't get the output written by time-grunt in the process exit callback. So I basically get all that's written up until the call to exit (i.e. all output from Grunt and Grunt tasks).

@vladikoff
Copy link

Results with @alimfeld patch:
PowerShell:
image

File Contents:

�[4mRunning "jshint:all" (jshint) task�[24m
�[31m>> �[39m0 files linted. Please check your ignored files.

�[32mDone, without errors.�[39m

cmd.exe:
image

File Contents:

�[4mRunning "jshint:all" (jshint) task�[24m
�[31m>> �[39m0 files linted. Please check your ignored files.

�[32mDone, without errors.�[39m

�[4mElapsed time�[24m
jshint:all  15ms  ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 100%
Total 15ms

@vladikoff
Copy link

Same results for grunt-karma.

So PowerShell with redirection doesn't get process.exit output. If that is fixed we might be good to go.

@cowboy
Copy link
Owner

cowboy commented Nov 26, 2013

There are 2 problems here.

  1. Grunt process hangs on Windows
  2. process.on('exit', fn) not working - Time-grunt stopped working after updating to grunt 0.4.2 sindresorhus/time-grunt#15

Let's use this issue to fix number 1, and fix number 2 in issue #7.

@cowboy
Copy link
Owner

cowboy commented Nov 26, 2013

Closed in 8b9b539.

@cowboy cowboy closed this as completed Nov 26, 2013
@cowboy
Copy link
Owner

cowboy commented Nov 26, 2013

v0.1.2 in npm, please test ASAP!

@Bartvds
Copy link

Bartvds commented Nov 26, 2013

@cowboy I confirm node-exit v0.1.2 solved my main issues:

  • the grunt-contrib-connect exits as expected (both via shell > redirect as in External Tool in WebStorm)
  • the grunt-karma tests exits as expected too.
  • time-grunt is still a no-show but I see you moved that to separate issue so that's cool.

Thanks for the progress so far! Epic bughunt!

@chrisgladd
Copy link
Contributor Author

Tested locally and with TeamCity issue, looks good. Thanks!

@EvgenyGusev
Copy link

My TeamCity issue has gone, everything works like a charm. Thanks, guys!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants