-
Notifications
You must be signed in to change notification settings - Fork 7.3k
New failing test: 'finish' firing before _flush is done in async case. #7612
New failing test: 'finish' firing before _flush is done in async case. #7612
Conversation
The 'finish' event is documented to fire with flushing is done: When "all data has been flushed to the underlying system". However, it appears be fired too early in the case of Transform streams which make an async call. process.nextTick is used here but I ran into this in a real-world case of making a call to a Mongo database. This new failing test illustrates the apparent bug. When the code is _flush is synchronous, there's no problem. It fails with both 0.10.x and the latest from the 0.11 branch as well.
@markstos I don't think it's a bug. Why would you even listen to |
|
Sorry, not a bug. |
In the case I found, the documentation disagrees with the code. One of them is wrong and should be updated. I provided test coverage for a case that had no coverage-- a async action in Transform._flush. Why reject test coverage for part of your system that is uncovered? @vkurchatkin I'm listening on the If you are going to keep the current behavior, I recommend at least merging and modifying the test coverage to match it. (I've re-pushed to that branch with a commit format that's updated to follow the contributing guidelines). The docs should then also be updated to note:
It looks to me more like a bug in the code than the docs, but if you'd if you'd prefer that I create a doc patch instead to clarify the current behavior, I could do that instead. |
For other people who run into this issue in the meantime, here's a workaround I've found: In my _flush method, I emit the 'close' event after calling the callback, and then listen for the |
I had this same problem when building a transform stream that did some buffered http requests. Are we just "doing it wrong"? I chose to use a transform stream because of the _flush method, which i felt i needed to use to do buffered writes of the data. It was the last stream in the pipeline i was building, so i wanted to listen for the "finish" event to know when the stream had completed processing all of its data. But because the http request is async, the finish event always fired prior to the last http request completing. Any tips for how to do this the right way, if the reported behavior is not a bug? |
That may sound like that, but this obviously can't give any guarantees about I can't see any use case for listening @chadxz when |
yeah the documentation might need some clarification between end and finish, I've been confused in the past myself but in a nut shell.
|
@vkurchatkin Thanks for the follow-up. I think the introduction to the _flush docs could use some updating to clarify that it is _flushing the readable side of the steam when used in Transform. This seems especially important as work is progressing in another issue to add _flush to Writable streams. To me, Call this function (optionally with an error argument) when you are done flushing any remaining data. Perhaps it would be better written as: Call this function (optionally with an error argument) to finish reading any remaining data. A use-case for using @calvinmetcalf Since you seem to understand the stream implementation beyond what the docs offer, could you improve the docs for For what's worth, using the var stream = new require('stream').Transform();
// Nothing interesting here
stream._transform = function (chunk, enc, next) {
next();
};
// _flush makes an async call.
stream._flush = function (callback) {
console.log("Expecting 1st: Entering _flush ");
return process.nextTick(function () {
console.log("Expecting 2nd: Done with _flush");
callback();
});
};
stream.on('end',function () {
console.log("Expecting 3rd: Entering finish callback-- should be flushed now.");
});
stream.end("chunk"); In the example above, the output from the |
you never read the stream, add an |
in this case you need to listen to anyway, if #7613 will be merged (and I hope it will) this problem will go away. |
Thanks @calvinmetcalf, that produces the expected result. |
@vkurchatkin The problem would go away because Transform would no longer have a I went to try applying the patch to a local 0.11 tree so I could test it, but I couldn't find _stream_readable.js under my I look forward to change from #7613. |
@markstos you need to build form source to try out the patch. Also right now it's incorrect |
+1 can't understand after reading the doc |
@yinrong there is ongoing related discussion on a proposed PR here: nodejs/node#2314 |
The cherry-pick of nodejs#7612 to v4.x (4369055) added in nodejs#9298 wasn't quite correct as it depends on a runtime function %SymbolDescriptiveString that doesn't exist on v4.x. We can use %SymbolDescription instead. Ref: nodejs/node#7612 Ref: nodejs/node#9298 PR-URL: nodejs/node#10732 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com> Reviewed-By: Myles Borins <myles.borins@gmail.com> Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
The cherry-pick of nodejs#7612 to v4.x (4369055) added in nodejs#9298 wasn't quite correct as it depends on a runtime function %SymbolDescriptiveString that doesn't exist on v4.x. We can use %SymbolDescription instead. Ref: nodejs/node#7612 Ref: nodejs/node#9298 PR-URL: nodejs/node#10732 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com> Reviewed-By: Myles Borins <myles.borins@gmail.com> Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
The 'finish' event is documented to fire with flushing is done: When "all
data has been flushed to the underlying system".
However, it appears be fired too early in the case of Transform streams
which make an async call. process.nextTick is used here but I ran into this
in a real-world case of making a call to a Mongo database.
This new failing test illustrates the apparent bug. When the code is
_flush is synchronous, there's no problem.
It fails with both 0.10.x and the latest from the 0.11 branch as well.