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

Hybrid node:http + fetch approach to node-fetch-server #33

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

cbnsndwch
Copy link

NOTE: all changes in this PR are non-breaking and implemented as separate, parallel exports except for:

  • added getter for the Host header to @mjackson/headers

  • updated platform field in packages/node-fetch-server/tsup.config.ts to 'node

  • implemented a custom IncomingMessage class that a node:http server can use as-is, and that implements the Request interface from undici-types

  • 5-10% faster than the base implementation in node-fetch-server

  • 15-20% faster than Express

  • added some basic unit tests to check parsing of sample requests works

Copy link
Owner

@mjackson mjackson 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 a good start, and the results from the benchmark are encouraging! I requested a few changes.

/**
* **DO NOT USE**, will always throw. Kept only for compatibility with type definitions.
*
* @deprecated Use `Request.formDataAsync()` instead which returns an `AsyncGenerator<MultipartPart>`
Copy link
Owner

Choose a reason for hiding this comment

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

Where is Request.formDataAsync defined? Is that a new spec? Or are you using the form-data-parser package?

Comment on lines +44 to +60
// const ac = new AbortController();
// this.on('close', () => {
// ac.abort();
// });

// let signal = ac.signal;
// this.#signal = ac.signal;

// if (signal.aborted) {
// ac.abort(signal.reason);
// } else {
// // Keep a strong ref to ac while request object
// // is alive. This is needed to prevent AbortController
// // from being prematurely garbage collected.
// // See, https://github.com/nodejs/undici/issues/1926.
// this[kAbortController] = ac;
// }
Copy link
Owner

Choose a reason for hiding this comment

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

Is this supposed to be uncommented? Seems like it, otherwise request.signal will be undefined.

Comment on lines +39 to +40
return http.createServer<IncomingMessage>(
{ IncomingMessage },
Copy link
Owner

Choose a reason for hiding this comment

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

Interesting! I had no idea the createServer API could use a custom IncomingMessage class. Very cool find 👍

},
"scripts": {
"bench": "bash ./bench/runner.sh",
"build": "tsup",
"test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts",
"debug": "node --import @swc-node/register/esm-register ./src/test.ts",
Copy link
Owner

Choose a reason for hiding this comment

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

It looks like ./src/test.ts is missing?


// hybrid magic
export { FetchIncomingMessage } from './lib/fetch-incoming-message/index.js';
export { createFetchServer } from './lib/create-fetch-server.js';
Copy link
Owner

Choose a reason for hiding this comment

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

Note: Ideally instead of creating two APIs we'd stick with a single API, createRequestListenener. Although I understand that you're exporting createFetchServer here under a different name so you can benchmark them both together.

Comment on lines +257 to +259
get host() {
return this.get('host');
}
Copy link
Owner

Choose a reason for hiding this comment

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

Can we please put this in a separate PR, and add a setter as well? Thanks 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants