Skip to content

feat(adapter): new uWebSockets adapter#103

Open
sandros94 wants to merge 15 commits into
mainfrom
feat/adapter-uws
Open

feat(adapter): new uWebSockets adapter#103
sandros94 wants to merge 15 commits into
mainfrom
feat/adapter-uws

Conversation

@sandros94
Copy link
Copy Markdown
Member

@sandros94 sandros94 commented Aug 22, 2025

Resolves #71

I wanted to take a shot at this, as it is a topic which I'm new but would like to understand. As such I want to warn that I've used extensively various LLMs to find docs and explain things, but final touch/edits/verifications were always human.

I tried to setup some benchmarks to distinguish from native node and uws, but failed. @pi0 I would love your help if and when you are available.

Tests run super smooth tho

@sandros94 sandros94 self-assigned this Aug 22, 2025
@sandros94 sandros94 requested a review from pi0 as a code owner August 22, 2025 16:01
@sandros94 sandros94 added the enhancement New feature or request label Aug 22, 2025
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Aug 22, 2025

Deploying h3-srvx with  Cloudflare Pages  Cloudflare Pages

Latest commit: d4a5698
Status: ✅  Deploy successful!
Preview URL: https://8b74922b.h3-srvx.pages.dev
Branch Preview URL: https://feat-adapter-uws.h3-srvx.pages.dev

View logs

@codecov
Copy link
Copy Markdown

codecov Bot commented Aug 22, 2025

@cyco130
Copy link
Copy Markdown

cyco130 commented May 20, 2026

Thanks for taking a shot at this. I'm not a maintainer or a contributor here, so pardon the intrusion. But I've implemented a similar adapter before and there are a few sharp edges in uWebSockets.js that need to be addressed:

Most importantly, uws.HttpRequest is stack allocated. It must be "gutted" before the callback returns synchronously, otherwise it can be overwritten by other data and all hell might break loose. See the docs, the very first paragraph mentions it (but without enough emphasis, imho).

It's probably best not to expose it to the user as user code may run after any number of awaits, where it's already too late. I would rather create a regular Headers object eagerly, on callback entry, and populate it with HttpRequest.forEach. Same goes for the URL and the method. They must be read and copied out of HttpRequest synchronously on callback entry, before entering any async path.

Alternatively, one could call the user handler, and if the return value is a promise, do the "gutting" at that point but I'd expect it to cause more complexity for little gain.

Another sharp edge is when reading the request body: The ArrayBuffer passed to the res.onData callback might be reused by uWebSockets.js if isLast is not true. So the data must be copied out immediately. So controller.enqueue(new Uint8Array(chunk)) is the wrong approach. We have to do something like:

const src = new Uint8Array(chunk);
const copy = new Uint8Array(chunk.byteLength);
copy.set(src);
controller.enqueue(copy);

for all but the very last chunk.

Also, onData must be attached synchronously, we can't wait until the body is read, or some data might be lost. Again, either call the user handler, and if it returns a promise without any attempt to read data, attach there (and pause it until needed). Another approach would be to attach it eagerly on entry and call pause until the body is needed.

I also see a few optimization opportunities like deferring the AbortController/AbortSignal pair creation until needed onAborted can just set a flag until then and if signal is accessed after onAborted fired, we can directly return AbortSignal.abort() without creating the controller. AbortController is somewhat expensive to create.

I also see some new APIs that I was not aware of, like res.onDataV2 that could allow preallocating a buffer when reading the whole body.

I'm also interested in seeing uWebSockets.js adapter merged. Drop me a line on Discord or check my profile for other contact info if you'd consider pairing on this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Node.js uws adapter

2 participants