Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # 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

# for free to join this conversation on GitHub. Already have an account? # 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