dd-trace-js icon indicating copy to clipboard operation
dd-trace-js copied to clipboard

use undici, for a faster HTTP implementation

Open bengl opened this issue 5 years ago • 4 comments

What does this PR do?

Uses undici instead of the regular node http API.

Before:

$ yarn bench:e2e -- --duration=300
avg latency overhead % 52.27722772277228
avg requests overhead % 47.5775574317691
avg throughput overhead % 47.564089591711856

After:

$ yarn bench:e2e -- --duration=300
avg latency overhead % 39.0928725701944
avg requests overhead % 35.334456624993926
avg throughput overhead % 35.315102625776994

Results may vary.

Motivation

Better performance.

bengl avatar Oct 07 '20 05:10 bengl

Can you provide more details as to why undici is so much faster? Is there something we could do internally that would be even faster without adding a library? This is especially true since it doesn't support Node 8 which we currently still support.

rochdev avatar Oct 07 '20 10:10 rochdev

Can you provide more details as to why undici is so much faster?

It skips a lot of the work involved in implementing node's http API. It reduces the usage of streams on the JavaScript side, unless you need them (we don't). It reduces object allocations. It also performs some lower-level tricks like corking and uncorking at various times to optimize packet sizes.

Is there something we could do internally that would be even faster without adding a library? This is especially true since it doesn't support Node 8 which we currently still support.

Maybe? A lot of the work is already done and tested by undici though, and since HTTP can get pretty complex, I'd rather note re-implement large parts of it, test those parts, and then hope we've covered all the weird edge cases. I don't think re-implementing its wins is a good use of time.

Instead, if we can't drop Node 8 support yet, undici could be an optionalDependency, and if it's not available we can fall back to http/https. How does that sound?

EDIT: To clarify the optionalDependency option, if it's in that section, it won't fail any installs. In our request code, we can check Node.js version numbers to see what's supported, and then act accordingly.

bengl avatar Oct 07 '20 15:10 bengl

This PR is not up to date with the branch. I had accidentally committed a bunch of garbage files, so I removed them, and while the branch is up to date, the PR is not, so I'd hold off until this is resolved by GitHub. I will contact GitHub support now.

bengl avatar Oct 09 '20 21:10 bengl

Should this be hidden behind an option at first since it's a major change?

Updated it to only use undici if the node versions supports it and experimental: { undici: true }

Also, I see that the library seems to be using promises in a few places which worries be given all the issues we have with them. Is any promise code path hit by the tracer?

It only seems to use promises in 2 places:

  1. In dispatch if you invoke it without callbacks. We're giving it callbacks.
  2. In Pool to handle connection lifetimes.

bengl avatar Oct 14 '20 20:10 bengl

@bengl dearest OP, it looks like some time has passed since this PR was kicked off. Is it something you'd like to drive on home or would it be safer to just close it for now?

tlhunter avatar Dec 20 '23 00:12 tlhunter

I'll close this PR for now but we can consider reopening it in the future.

tlhunter avatar Jan 12 '24 17:01 tlhunter