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

http: always call response.write() callback #27709

Closed
wants to merge 1 commit into from

Conversation

lpinca
Copy link
Member

@lpinca lpinca commented May 15, 2019

Ensure that the callback of OutgoingMessage.prototype.write() is
called even when writing empty chunks.

Fixes: #22066

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • commit message follows commit guidelines

Ensure that the callback of `OutgoingMessage.prototype.write()` is
called even when writing empty chunks.

Fixes: nodejs#22066
@nodejs-github-bot
Copy link
Collaborator

@nodejs-github-bot nodejs-github-bot added the http Issues or PRs related to the http subsystem. label May 15, 2019
@lpinca
Copy link
Member Author

lpinca commented May 15, 2019

This is an attempt to fix #22066.
The idea is to treat empty chunks like all other chunks and write them to the socket. In this way

  • The callback is called in and called the correct order.
  • We can return the correct boolean value, the one returned by socket.write(), instead of blindly returning true.

The downside is that internal empty writes like

this._send('', 'latin1', finish);
now trigger a socket.write() call which in turn calls into C++. This could have an impact on performance if writev is not supported. A possible way to mitigate the issue is to not call writeGeneric() if the chunk is empty here

node/lib/net.js

Line 696 in 53bef42

req = writeGeneric(this, data, encoding, cb);

If we don't care about the callbacks order, we can simplify everything and just call the callback of OutgoingMessage.prototype.write() in the next tick when an empty chunk is written.

Copy link
Member

@addaleax addaleax left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is my preferred approach as well 👍

@Trott Trott added the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label May 18, 2019
@nodejs-github-bot
Copy link
Collaborator

@nodejs-github-bot
Copy link
Collaborator

@nodejs-github-bot
Copy link
Collaborator

@nodejs-github-bot
Copy link
Collaborator

@addaleax
Copy link
Member

Landed in 0df581c

@addaleax addaleax closed this May 19, 2019
addaleax pushed a commit that referenced this pull request May 19, 2019
Ensure that the callback of `OutgoingMessage.prototype.write()` is
called even when writing empty chunks.

Fixes: #22066

PR-URL: #27709
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
@lpinca lpinca deleted the gh-22066 branch May 20, 2019 05:19
lpinca added a commit to lpinca/node that referenced this pull request May 20, 2019
Ensure that the callback of `OutgoingMessage.prototype.write()` is
called when `outgoingMessage._hasBody` is `false` (HEAD method, 204
status code, etc.).

Refs: nodejs#27709
targos pushed a commit that referenced this pull request May 20, 2019
Ensure that the callback of `OutgoingMessage.prototype.write()` is
called even when writing empty chunks.

Fixes: #22066

PR-URL: #27709
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
@BridgeAR BridgeAR mentioned this pull request May 21, 2019
4 tasks
Trott pushed a commit to Trott/io.js that referenced this pull request Jun 1, 2019
Ensure that the callback of `OutgoingMessage.prototype.write()` is
called when `outgoingMessage._hasBody` is `false` (HEAD method, 204
status code, etc.).

Refs: nodejs#27709

PR-URL: nodejs#27777
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Rich Trott <rtrott@gmail.com>
targos pushed a commit that referenced this pull request Jun 1, 2019
Ensure that the callback of `OutgoingMessage.prototype.write()` is
called when `outgoingMessage._hasBody` is `false` (HEAD method, 204
status code, etc.).

Refs: #27709

PR-URL: #27777
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Rich Trott <rtrott@gmail.com>
@awwright
Copy link
Contributor

awwright commented Sep 24, 2019

What's the test case that this fixes?

This PR seemed to introduce a bug where the callback for OutgoingMessage#end is not always called, since the callback for Writable#write doesn't always call if passed an empty string (where as before this PR, OutgoingMessage#_writeRaw did guarantee this).

But this PR was supposed to fix such an issue, so I'm not sure what's going on here.

@lpinca
Copy link
Member Author

lpinca commented Sep 24, 2019

@awwright see #22066 (comment) and included tests.

@awwright
Copy link
Contributor

But #22066 (comment) is incorrect, Stream#write has no guarantee in the code that the callback will always be called, see #29649 for an example

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
author ready PRs that have at least one approval, no pending requests for changes, and a CI started. http Issues or PRs related to the http subsystem.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

http: Stream#write with an empty buffer does not call callback
6 participants