-
Notifications
You must be signed in to change notification settings - Fork 29.6k
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
zlib: only apply drain listener if given callback #3534
Conversation
I'm not sure what the official process is for grabbing commits from pr's from the archive. I opted to cherry pick the commit and update the commit message, but retained the authorship with the original author. |
Is there some way to add a test for this? |
most likely. I'm more than happy to try and take on some of that work, but would love to see if this would be an acceptable solution before putting in time... especially since I'm not 100% on exactly how to test it yet :P |
if (callback) { | ||
this.once('drain', function() { | ||
self.flush(callback); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I spot a bug here: the call should be self.flush(kind, callback)
, it forgets the kind
now.
Also, I'd ES6 this up and write it as this.once('drain', () => this.flush(kind, callback))
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
This seems about right. :) |
There were a few different things that have come in from the thread so I have split them up . First was the bug that @bnoordhuis spotted where kind was not being to recursive calls of flush. This part should be able to be backported even if the rest of this PR is deemed semver breaking. I also included a separate patch to explicitly check that callback is a function rather than just truthy. This was originally requested by @cjihrig in the original thread This pattern does appear throughout the codebase in both ways... I'm going to make a separate issue about this. It is also worth bringing up that @jasnell mentioned in the original thread that the zlib docs do not state that the callback is optional... so the docs may need to be updated. |
meta conversation about how callbacks are dealt with --> #3536 |
My personal opinion is that you should try to maintain the original author of the commit when cherry picking. |
@@ -438,16 +438,15 @@ Zlib.prototype.flush = function(kind, callback) { | |||
} | |||
|
|||
if (ws.ended) { | |||
if (callback) | |||
if (typeof callback ==='function') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a space between ===
and 'function'
throughout this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
got it
Regression tests would be good.
I agree but 9d9f681 doesn't look like a cherry-pick to me. |
@bnoordhuis I could have sworn I responded to this already 😵 that commit does differ from the original, but only in as far as changes were requested in this thread... seems like a fine line to me, so I opted to be conservative here |
is the lack of a test the only thing holding this up atm? |
Yes. I'd drop 0865370 for now because it makes it semver-major instead of just a bug fix. |
kk. I'll leave that to get cleaned up by #3539 |
@thealphanerd status of this? |
@Fishrock123 planning to work on this today actually. Just have not had time to figure out how to test the change yet. |
@thealphanerd Status? |
Still trying to wrap my head around Zlib, specifically the streams bit. Will focus on this today and hopefully have something tangible |
I just pushed a first pass at doing a test.
Now I'm not 100% that there is no way that calling flush right after write may have flush execute while it's internal write stream is not needing to drain. (Which would cause this test to fail) If anyone has suggestions on how to improve this I am very interested. I would also be interested if anyone has a better practice for spying on functions as I did with the flush shim. |
The failing CI bits seem unrelated to this PR to me |
}); | ||
|
||
deflater.on('drain', function() { | ||
drained = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I understand the logic of this test right, I'd turn this into a counter and check that it's equal to flushCount
on exit. If I don't understand the logic right, I'd still turn it into a counter and check that it has the expected value. :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
drain should only execute once if I recall correctly, but I can double check that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok I've checked, and drain is only emitted once (as expected). That being said I will make it a counter rather than checking a boolean state
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is now fixed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm still seeing a boolean (or again? I could swear you'd made the changes.)
LGTM |
LGTM but can you run the CI again and would you mind fixing the spelling of my GH handle in the first commit? |
Commit updated new ci --> https://ci.nodejs.org/job/node-test-pull-request/722/ I'm more than happy to land this after the CI run, should this all be flattened to a single commit or is it alright to land as three? |
Bug spotted by @bnoordhuis while doing code review on #3534 #3534 (comment)
When stream.flush() is called without a callback, an empty listener is being added. Since flush may be called multiple times to push SSE's down to the client, multiple noop listeners are being added. This in turn causes the memory leak detected message.
Bug spotted by @bnoordhuis while doing code review on #3534 Refs: #3534 (comment) PR-URL: #3534 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: James M Snell <[email protected]>
When stream.flush() is called without a callback, an empty listener is being added. Since flush may be called multiple times to push SSE's down to the client, multiple noop listeners are being added. This in turn causes the memory leak detected message. PR-URL: #3534 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: James M Snell <[email protected]>
This test assures that if flush is called while the zlib object needs to be drained that it will defer the callback until after the drain. PR-URL: #3534 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: James M Snell <[email protected]>
Bug spotted by @bnoordhuis while doing code review on #3534 Refs: #3534 (comment) PR-URL: #3534 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: James M Snell <[email protected]>
When stream.flush() is called without a callback, an empty listener is being added. Since flush may be called multiple times to push SSE's down to the client, multiple noop listeners are being added. This in turn causes the memory leak detected message. PR-URL: #3534 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: James M Snell <[email protected]>
This test assures that if flush is called while the zlib object needs to be drained that it will defer the callback until after the drain. PR-URL: #3534 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: James M Snell <[email protected]>
Bug spotted by @bnoordhuis while doing code review on #3534 Refs: #3534 (comment) PR-URL: #3534 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: James M Snell <[email protected]>
When stream.flush() is called without a callback, an empty listener is being added. Since flush may be called multiple times to push SSE's down to the client, multiple noop listeners are being added. This in turn causes the memory leak detected message. PR-URL: #3534 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: James M Snell <[email protected]>
This test assures that if flush is called while the zlib object needs to be drained that it will defer the callback until after the drain. PR-URL: #3534 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: James M Snell <[email protected]>
Bug spotted by @bnoordhuis while doing code review on #3534 Refs: #3534 (comment) PR-URL: #3534 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: James M Snell <[email protected]>
When stream.flush() is called without a callback, an empty listener is being added. Since flush may be called multiple times to push SSE's down to the client, multiple noop listeners are being added. This in turn causes the memory leak detected message. PR-URL: #3534 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: James M Snell <[email protected]>
This test assures that if flush is called while the zlib object needs to be drained that it will defer the callback until after the drain. PR-URL: #3534 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: James M Snell <[email protected]>
When stream.flush() is called without a callback, an empty listener is
being added. Since flush may be called multiple times to push SSE's
down to the client, multiple noop listeners are being added. This in
turn causes the memory leak detected message.
fixes #3529
This commit has been cherry picked from a pr on v0.x-archive
nodejs/node-v0.x-archive#25679