-
Notifications
You must be signed in to change notification settings - Fork 30k
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: Add noDelay to http.request() options. #31539
base: main
Are you sure you want to change the base?
Conversation
Hi, what is the purpose of this? Default is no delay is true (so nagle is off). Is there any time you would want nagle on for HTTP? I can't think of one. Is there any way that http.request() would somehow get a net Socket that had nagle turned on still? I can't think of one, but I might be missing some corner case. |
@sam-github Hi, I'm sure your tone is nice and friendly but others might interpret it as a bit aggressive and unwelcoming asking what the purpose is. I think the patch is quite clear in its purpose. By default tcp sockets are created with the Nagle's delay algorithm enabled. See https://en.wikipedia.org/wiki/Nagle%27s_algorithm. Would you be kind enough to show where you think the default disabling of TCP_NODELAY being set? That call isn't happening in the |
re. TCP_NODELAY I don't think we ever did implement #906. |
My apologies @rustyconover, I don't mean to discourage you. Your description was quite clear in the what, but if you look at it again, you will notice that it does not say anything about why, and it is difficult to review a PR without understanding what goal it achieves.
My assumption was the documentation was correct, though given the conversation @richardlau linked to, it seems it is not. :-( |
@sam-github It is all good. My goal is to allow people to control disabling the delay in HTTP options rather than forcing users to call .setNoDelay() on each connection after the fact. It is quite difficult in some code that only takes high-level HTTP options (such as the AWS SDK) to get them to surface the actual request objects that are created so I can disable the Nagle algorithm. Making noDelay available on the HTTP options lets me achieve this goal with the minimum of fussing around. |
@sam-github Also the docs imply the default for the parameter to |
I think so. There was a previous attempt at this (#7995) but it stalled out. |
While I'm ok with this in general, I think we should (as a separate activity) explore a better model for passing options down to internal dependent components in general. We have this exact kind of problem (passing options down) in multiple areas and we end up dealing with it in one off ways every time. |
This is greeeat! It would be nice to cherry pick the stuff from #31541 |
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 not sure how I feel about this – if you want to set socket options manually, wouldn’t createConnection()
be a more sensible place to do this (as this is more concerned with networking and not really with HTTP itself)?
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.
After checking, it looks like the net
module does not provide an option like this – I think that if we add this to HTTP, we should definitely also add it to net.Socket
. But again, it feels to me like this is better kept on the networking side only.
@addaleax Hi, I'm happy to add the same functionality to I believe having the noDelay option at the HTTP level is ok right now. The reason is a lot of popular high level packages don't expose the underlying network sockets they use to the user but they typically do expose HTTP options. By not having the functionality here to disable Nagle's algorithm, you're asking every user to pass a custom HTTP Agent that would then hook the By default all TCP connections have Nagle's algorithm enabled, which is less than optimal for HTTP/HTTPS. Until that changes (i.e. Node decides to disable it by default for HTTP/HTTPS) and it seems like this is the best way forward. I'm interested to know what you think. |
cf9e4ef
to
35ace28
Compare
@rustyconover To be clear, I’m not opposed to having an option like this in HTTP. However, I’d prefer to have this in I’m okay with this waiting for a PR for |
Add the noDelay option to the http.request() options such that .setNoDelay() will be called once a socket is obtained. Add note about noDelay only applying to a TCP socket.
Add the noDelay option to the net.Socket() options such that .setNoDelay() will be called when a socket is created
35ace28
to
24697c2
Compare
@addaleax I've added the options to |
@jasnell can you please add the author-ready tag? |
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 this should have some tests.
8ae28ff
to
2935f72
Compare
@sam-github @richardlau I have posted a new PR that replaces the closed #906 and again pushes for changing the default behavior to be |
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 we might want to set this also for tls.
Moreover, we need tests.
@mcollina I think tests for this feature run the risk of not showing anything interesting as the TCP_DELAY behavior isn't super deterministic between operating systems or even versions of the same operating system. Do you have an idea of an adequate test plan? |
@@ -417,6 +417,9 @@ added: v0.3.4 | |||
* `allowHalfOpen` {boolean} Indicates whether half-opened TCP connections | |||
are allowed. See [`net.createServer()`][] and the [`'end'`][] event | |||
for details. **Default:** `false`. | |||
* `noDelay` {boolean} A boolean with which to call [`socket.setNoDelay()`][] | |||
when a socket connection is established. This only applies when the | |||
underlying connection is a TCP socket. |
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.
Please add default values.
I would just override the |
So basically: Override the That's good enough as far as tests goes? |
I think so, yes. |
@rustyconover Do you plan to keep working on this? |
This issue/PR was marked as stalled, it will be automatically closed in 30 days. If it should remain open, please leave a comment explaining why it should remain open. |
Sure, I think I'll keep at it. |
@rustyconover Feels like the tests should be fairly quick to wrap up, need some help or you have time to fix them yourself? |
Stalled again. |
would you like to pick it up @bl-ue? |
Ah @mcollina, I feel honored by your offer 😁 ❤️, but I'm afraid I've neither the time nor the expertise in this area to continue it :/ |
@rustyconover are you still interested in pursuing this? |
I'm still interested in landing this... |
This isn't a breaking change, right? So it can go out in any minor? So not important to eg. get it into #40119 ? |
I prefer the option being on the |
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 please add YAML entries similar to
Lines 545 to 548 in 6fdd582
changes: | |
- version: v15.14.0 | |
pr-url: https://github.com/nodejs/node/pull/37735 | |
description: AbortSignal support was added. |
Add the noDelay option to the http.request() options such that
.setNoDelay() will be called once a socket is obtained.
make -j4 test
(UNIX), orvcbuild test
(Windows) passes