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

refactor: update Reply module #4072

Merged
merged 6 commits into from Jul 1, 2022
Merged

Conversation

denshakhov
Copy link
Contributor

Hi, I refactored the Reply module a little bit.

  • Use node.js 14 syntax
  • Improve code readability
  • Reuse Reply's methods where possible

Tests are passing, the benchmark result is the same as before.

Checklist

* Use node.js 14 syntax
* Improve code readability
* Reuse Reply's methods where possible
lib/reply.js Outdated Show resolved Hide resolved
lib/reply.js Outdated
// it must be chunked for trailer to work
reply.header('Transfer-Encoding', 'chunked')
reply.header('Trailer', header.trim())
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think we can completely delete filter here (and also in sendTrailer()) because it's already validated in Reply.prototype.trailer(), but if we leave it, then we must also check it for invalid trailers (INVALID_TRAILERS), wdyt?

Copy link
Member

Choose a reason for hiding this comment

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

No, removeTrailer will set the value to undefined. It is required to check if the value is function.

INVALID_TRAILERS is not the same case, as it never be able to set the invalid key-value pair. There is no need to check it again.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👌

lib/reply.js Outdated Show resolved Hide resolved
lib/reply.js Outdated Show resolved Hide resolved
lib/reply.js Outdated Show resolved Hide resolved
lib/reply.js Outdated Show resolved Hide resolved
lib/reply.js Outdated Show resolved Hide resolved
lib/reply.js Outdated Show resolved Hide resolved
lib/reply.js Outdated Show resolved Hide resolved
Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

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

I'm not fond of this massive changes in syntax. I would prefer if we hold off from doing these unless there are specific needs.

lib/reply.js Outdated Show resolved Hide resolved
lib/reply.js Outdated Show resolved Hide resolved
lib/reply.js Outdated
// it must be chunked for trailer to work
reply.header('Transfer-Encoding', 'chunked')
reply.header('Trailer', header.trim())
reply.header('Trailer', Object.keys(reply[kReplyTrailers]).filter(trailer => typeof reply[kReplyTrailers][trailer] === 'function').join(' '))
Copy link
Member

Choose a reason for hiding this comment

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

filter() is very slow.

lib/reply.js Outdated
reply[kReplyHeaders]['content-length'] = '' + Buffer.byteLength(payload)
} else if (req.raw.method !== 'HEAD' && reply[kReplyHeaders]['content-length'] !== Buffer.byteLength(payload)) {
reply[kReplyHeaders]['content-length'] = '' + Buffer.byteLength(payload)
if (!reply.hasHeader('content-length') || (req.raw.method !== 'HEAD' && parseInt(reply.getHeader('content-length'), 10) !== Buffer.byteLength(payload))) {
Copy link
Member

Choose a reason for hiding this comment

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

please use the fast-path for getHeader.

lib/reply.js Outdated Show resolved Hide resolved
lib/reply.js Outdated
}

Reply.prototype.removeTrailer = function (key) {
if (this[kReplyTrailers] === null) return this
this[kReplyTrailers][key.toLowerCase()] = undefined
if (this[kReplyTrailers] !== null) {
Copy link
Member

Choose a reason for hiding this comment

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

I think I add it as a early exit approach.
The readability didn't change a lot when here is few line of code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👌

lib/reply.js Outdated
for (var i = 0; i !== keys.length; ++i) {
const key = keys[i]
this.header(key, headers[key])
for (const headerName in headers) {
Copy link
Member

Choose a reason for hiding this comment

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

There is a significant difference between Object.keys and for...in:

for...in https://262.ecma-international.org/13.0/#sec-createforiniterator:

It is used to create a For-In Iterator object which iterates over the own and inherited enumerable string properties of object in a specific order.

Object.keys https://262.ecma-international.org/13.0/#sec-object.keys:

    1. Let nameList be ? EnumerableOwnPropertyNames(obj, key).

In short, the Object.keys implementation does not enumerate properties from higher up in the prototype chain. It only iterates the actual headers object properties.

lib/reply.js Outdated
@@ -165,6 +165,7 @@ Reply.prototype.send = function (payload) {
// If user doesn't set charset, we will set charset to utf-8
if (contentType.indexOf('charset') === -1) {
const customContentType = contentType.trim()

Copy link
Member

Choose a reason for hiding this comment

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

What is happening here? Is this a line ending change?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nope, just a new line to separate var definition and if condition (I added it when I was refactoring this reverted block of code). Delete?

lib/reply.js Outdated Show resolved Hide resolved
lib/reply.js Outdated Show resolved Hide resolved
lib/reply.js Outdated Show resolved Hide resolved
Copy link
Member

@jsumners jsumners left a comment

Choose a reason for hiding this comment

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

Looks good to me.

@mcollina
Copy link
Member

CI is failing

@denshakhov
Copy link
Contributor Author

Looks like CI is passing after I merged in the main branch.

Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

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

lgtm

@mcollina mcollina merged commit c525e67 into fastify:main Jul 1, 2022
@github-actions
Copy link

github-actions bot commented Jul 2, 2023

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jul 2, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants