nodejs-dns-over-https-tangerine icon indicating copy to clipboard operation
nodejs-dns-over-https-tangerine copied to clipboard

[feat] parallel resolution

Open Kikobeats opened this issue 9 months ago • 6 comments

Describe the feature

I recently installed AdGuard Home on my local network and enabled the following feature:

Image

It's great because you no longer have to worry about whether your DNS is fast or not – simply the fastest will be used.

I was wondering if Tangerine can implement this way of DNS resolution.

Checking the Tangerine source code, I can see requests are resolved in series, so the server index in the array is important:

https://github.com/forwardemail/nodejs-dns-over-https-tangerine/blob/42da3ee7c4e9f1200233f2acdb47f8c9bf01d7d4/index.js#L1112

This parallel resolution could be achievable using p-any; it also supports cancellation, so as soon as the first promise for getting the DNS resolution is resolved, the rest will be cancelled, preventing a waste of resources.

WDYT?

Kikobeats avatar Mar 30 '25 18:03 Kikobeats

This sounds great, could you add this as a PR with a configurable option series or parallel or something? Or maybe just parallel: true is the default. @Kikobeats

titanism avatar Mar 31 '25 21:03 titanism

That sounds good – we can keep "series" by default to mimic the current behavior.

I have to find the time for writing this, so let's keep this issue open 🙂

Kikobeats avatar Apr 01 '25 16:04 Kikobeats

@titanism I want to land this, however tests are failing now on the main branch.

Can you check if they pass green on CI? 🙏

Kikobeats avatar Jul 20 '25 20:07 Kikobeats

Tests are not passing right now I believe and haven't in some time. Need to refactor them some. Nothing functionality wise is broken, just the tests need fixed up a bit.

I don't think you need to use p-any, and if you did, you'd have to use v3 not v4 because we use CJS here not ESM.

In any case, it'd be something like this:

try {
  await Promise.any([promise1, promise2, promise3]);
} catch (err) {
    console.log("Error type:", err.name); // Output: AggregateError
    console.log("Error message:", err.message); // Output: All promises were rejected
    console.log("Rejection reasons:", err.errors); // Output: [Error: Failed 1, Error: Failed 2, "Failed 3"]
    console.log("Full error:",err);
}

titanism avatar Jul 21 '25 10:07 titanism

PR welcome

titanism avatar Jul 21 '25 10:07 titanism

I mean I can't do the PR until test pass gren otherwise I don't know if I'm breaking code

Kikobeats avatar Jul 21 '25 14:07 Kikobeats