-
Notifications
You must be signed in to change notification settings - Fork 29.8k
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
added before-flushing-head event to _http_server.ServerResponse.writeHead #2538
Conversation
I believe this has to be well documented and should have proper tests. |
Should it emit any of the arguments |
@thefourtheye - I have added docs and a test. @Fishrock123 - I do not think it should get any parameters. When you set the event listener you have a reference to the res object. At that same point you can use the same res object to customize the response head before flushing it. |
@Fishrock123 - thinking about this again - given how the code looks like now, you cannot modify the head status code or message. Do you think we should enable customizing those as well? (you can customize headers via the APIs exposed on the res object. However, because writeHead takes the statusCode and reason as parameters, the res API cannot really update them at this point. |
@yoavaa a crazy idea that would allow arg modification: function writeHead(statusCode, reason, obj) {
var args = { statusCode, reason, obj }
this.emit('before-flushing-head', args);
this._writeHead(args);
} |
The function itself allows a more complex handing of the args - it starts by checking for missing args and reordering them
also, right after that the function copies headers from the _header member into obj, allowing the event handler to add additional headers using the response public APIs.
because of this if we want the event to allow modification of the response code, response message and headers we are forced into emitting the event only after the second code block and effectively preventing users from modifying the headers using the If we go with that, this is the new method (below). The event now gets the args object which includes
the method
|
@Fishrock123 @yoavaa @thefourtheye ... any further thoughts on this? |
@nodejs/http |
I like the idea, and I have seen some use cases for this myself. The only minor question that I have is about event name. We are definitely using camel case for them in core, should we consider doing it the same way here as well? |
+1 for consistency |
@indutny so we should rename the event to |
I'm not a native speaker, but it looks good to me. cc @jasnell ? |
Works for me. |
renamed the event. |
var common = require('../common'); | ||
var assert = require('assert'); | ||
var http = require('http'); | ||
|
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 use const
for requires
Few additional nits. |
ok, I have addressed the code formatting issues above and found and (and fixed) a few bugs, as well as updated the docs. |
+1 |
@jasnell, can we proceed with merging this pull request. |
@jasnell Just did rebase, and tests are green |
@nodejs/http @nodejs/ctc ... any additional comments on this one? |
@yoavaa Can you clarify your definition of "time to first byte"? I can think of several ways to define this that run in contradiction to this PR. |
@trevnorris I agree that measuring time to first byte, when talking about it in most cases, refers to the client (browser or another http client) measuring the time from issuing the request until it gets back the first byte of response. This time normally includes DNS lookup, network latency, server request queuing and server request processing. What I refer to, in this case, is the server view of time to first byte - that it, the time between getting the request (user code) and the time the first bytes are sent out of the server (again, user code). This metric is useful to separate the impact of a user code from the rest of the variables that are less under control (like geo latency, network latency, DNS, etc). This PR gives a notification just before node writes the HTTP head, it is a good indication of the time to first byte sent by node (ignoring any network buffers on the node side). Does that makes sense? |
Thinking about this further in relation to #1873. |
@jasnell, I have looked into changing the implementation to support the headers added by
The second option is actually the better because it ensures that the event is emitted exactly when needed - just before sending the body.
so, what do you think? should we make this change? |
Note sure there will be a major performance impact. But we do have a side effect of including outgoing messages from HTTP client as well - requiring there a similar change as well. |
7da4fd4
to
c7066fb
Compare
c133999
to
83c7a88
Compare
@yoavaa ... is this still something you'd like to pursue? |
Closing due to lack of forward progress on this |
The before-flushing-head event is needed for monitoring of HTTP requests and capturing the time to first byte as well as for enabling middleware to write headers to responses. TTFB (time to first byte) is important measurement as it measures the server performance regardless of sending data down the stream and it actually what most monitoring tools measure on the client side, including google with their page speed and SEO engines.
Today we have to resort to using a wrapper for this method, but I think it is a great functionality to have in node.js