-
Notifications
You must be signed in to change notification settings - Fork 20
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
Thoughts on a Web APIs (fetch) based http server (replacing node:http
)
#18
Comments
node:http
)
node:http
)node:http
)
node:http
)node:http
)
PS: I know I just did the entire opposite of what the tweet said but I think there may be something worth exploring here. Sorry @mjackson 😁 |
Sorry for the slowness on my reply here. I told you I didn't want to get sucked into this! 😅 Having said that, the path I was thinking about going was to use node:net together with milo for HTTP parsing. All server logic could be written in JavaScript/TypeScript. I'd personally prefer to have the core server logic written in JavaScript/TypeScript (instead of e.g. Rust) to make it a little easier for JS devs to contribute.
Yes, I definitely agree there is something worth exploring here. My current focus is making Remix and tools for Remix at the application layer that work with any JS runtime (Node.js, Deno, Bun, etc.), and we already have a thin wrapper around node:http that gives us good enough performance on Node.js, so I'm not very inclined to work on this myself. But if you've got the itch to contribute and you'd like to see something happen here I'd be happy to act as an advisor (and maybe even contribute some code as needed). But I'd need you to be the main driver. |
Makes sense! Will take a look and post back |
Oooh boy, it's been quite a journey so far haha! Stopping over here to say I'm still looking into it every chance that I get. Keep the seat warm, if you will. Here's what I've learnt so far:
|
Thanks for the report! I know very little about WASM, but it makes sense to me that there would be a perf hit there. AFAIK they are planning on using milo in node core sometime soon, but they're almost certainly not planning on using the WASM version. Would it be worth it to do a spike with the WASM version just to get the ball rolling? |
Did some more digging into That gave and idea of simplifying the adapter pattern you've got going on from Just by skipping a lot of checks My hypothesis is that by giving Seems promising, will test some more and come back with results |
Just to make sure I understand... are you saying I can tell |
Yep! Check out the option object accepted by https://nodejs.org/docs/latest-v20.x/api/http.html#httpcreateserveroptions-requestlistener It feels like a hack but by passing in a class that extends
|
Welp definitely confirmed that passing in a custom request constructor to Perf is still not great which may be due to still needing to copy the response back to the Will try to add tracking to different parts of the listener to confirm |
Here's what it's looking like now on my laptop, in this run about Platform: Linux 5.15.167.4-microsoft-standard-WSL2
CPU: Intel(R) Core(TM) i9-14900HX
Date: Date: 11/24/2024, 1:34:43 PM
Saving stats to: ~/fetchification/packages/node-fetch-server-2/bench/runs
Running benchmark for node:[email protected] ...
Waiting 5 seconds for the server to start ...
Running 30s test @ http://127.0.0.1:3000/
12 threads and 400 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 15.64ms 76.95ms 1.56s 98.50%
Req/Sec 4.40k 668.00 18.81k 96.15%
1558723 requests in 30.05s, 319.60MB read
Requests/sec: 51866.90
Transfer/sec: 10.63MB
Running benchmark for [email protected] ...
Waiting 5 seconds for the server to start ...
Running 30s test @ http://127.0.0.1:3000/
12 threads and 400 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 26.50ms 99.51ms 1.99s 98.45%
Req/Sec 2.08k 426.17 8.28k 94.34%
721170 requests in 30.05s, 147.87MB read
Socket errors: connect 0, read 0, write 0, timeout 104
Requests/sec: 23999.21
Transfer/sec: 4.92MB
Running benchmark for [email protected] ...
Waiting 5 seconds for the server to start ...
Running 30s test @ http://127.0.0.1:3000/
12 threads and 400 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 28.76ms 94.99ms 2.00s 98.60%
Req/Sec 1.72k 431.00 8.67k 94.83%
593894 requests in 30.09s, 143.29MB read
Socket errors: connect 0, read 0, write 0, timeout 121
Requests/sec: 19739.43
Transfer/sec: 4.76MB |
After this tweet from @mjackson:
I started thinking about what it would take to actually replace
node:http
with an http server that directly implements Web APIs as described in README.md:Took a deep dive into the source code of
node:http
andnode:net
to see what we would be working on and here are my thoughts:No soup for you!
The files that make up
node:http
rely heavily on Node internal objects and functions that are not available to userland JS.primordials
objectinternalBinding('MODULE_ID
)` functionhttp_parser
module (internal binding)internal/http
,internal/async_hooks
,internal/errors
, etcReplicating the functionality of
node:http
while still relying onnode:net
is then gonna require adding a new built-in module to Node and getting it merged. It won't be possible directly from userlandEnter the multi-(language)-verse
One alternative I thought of is building a native addon that bundles a different http server and exposes a Web API-based interface to JS, while staying as close to
node:http
as possible:There are viable options in Rust (https://hyper.rs/, https://actix.rs/) and in Go (https://gofiber.io/, https://github.com/go-chi/chi, https://gorilla.github.io/) that can be compiled as Node native modules.
Encore.ts seems to be doing something like this but they've gone the "batteries included" route where the value prop only makes sense if you switch your entire runtime and app architecture to their library. Ideally whatever I would build would only aim to provide an alternative to
node:http
and not become an entire stack.This path would be a lot of work so before I keep going down the rabbit hole your feedback would be greatly appreciated 🤓
The text was updated successfully, but these errors were encountered: