-
Notifications
You must be signed in to change notification settings - Fork 3
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
error()
should flush stdout before emitting message
#258
Comments
Ok. So, a lot of digging on this, indicates that this is a continuing sore-point in Node.js in general. Here are some open issues related to this problem: elm-explorations/test#138 In the current Node.js documentation regarding https://nodejs.org/docs/latest-v14.x/api/process.html#process_a_note_on_process_i_o When the output is asynchronous, we run into a sticky situation when One model for dealing with this issue is to essentially turn everything into an asynchronous case, where the 'top level' code flow 'finishes' very quickly, and all program logic happens within code that is being waited upon. This does not mean that I did find one other approach which appears to work, but, may have a slight slowing effect, and how much this effect has will vary somewhat depending on how much output is being done. In our case, I believe this is mostly limited to cases where we are emitting error details. This approach is to set a flag which causes the output to become blocking. ie: [process.stdout, process.stderr].forEach((stream: any) => {
if (stream._handle && typeof stream._handle.setBlocking === 'function') {
stream._handle.setBlocking(true);
}
}); It's not clear to me yet how this flag being set actually brings about the change that's observed, but it does appear to provide the desired result. Perhaps it avoids use of the buffer that would normally be used, and sends data instead to the output, and results in a system-level blocking function effectively putting the brakes on until the content is consumed by the other end of the pipe? |
Here is a fairly simple way to observe the effect of this issue:
For the above, I am observing this result: 65546
For the above command, I observe the expected result: 5000010 |
Very interesting. Thanks for putting this detailed information together. Do you, then, propose that we set blocking to |
Yes, but, my testing so far shows that for this to work, it actually can not be done at the last minute. It has to be done before the buffering of the output stream becomes involved, from what I can see. Since this is actually a Node.js problem rather than |
Maybe the best middle ground would be to make this a default-enabled option, but allow people to disable it when initializing Waterfall CLI. Thoughts? |
I am not against that. I will do some testing to see if that's a viable option. Meanwhile, unfortunately, we might need a combination approach. Even though I had set the
In the client code before the call to So, there appears to be more to the story than just setting |
Huh; this is proving much more challenging than we thought! |
I am now seeing that even with the I wonder if the fix for this issue varies depending on whether the client code is synchronous or not? If I make the If the exact same function is used from a synchronous context, the I think this might be a decent way to go, unless we want to have 2 flavors of For clarity: The
and, in the client, within an async function, would use:
|
I think that's a reasonable approach. If we release this library publicly, we'll want to document these things. |
It appears that there are circumstances where the
waterfall-cli.error()
, which outputs to stderr and then terminates execution, may actually emit it's output before stdout has been emptied.From a client perspective, putting the following code before calling
waterfall-cli.error()
appears to allow stdout to be completed before the error message is output (from a function with 'async' declared):Instead of putting this flushing of stdout before every
waterfall-cli.error()
usage within client code, it makes sense to me that this should be put within theerror()
directly, so that it can be put in one place once, rather than many other places in the client code.There is documentation about how the mode of operation of stdout and stderr changes based on the usage scenario at: https://nodejs.org/api/process.html#process_a_note_on_process_i_o, which makes it clear that there is different behavior when the output is being piped (asynchronous) versus non-piped (synchronous) on POSIX (unix-like) usages.
The text was updated successfully, but these errors were encountered: