nodejs / node

Node.js JavaScript runtime ✨🐢🚀✨
https://nodejs.org
Other
107.46k stars 29.55k forks source link

dns.lookup timeout / cancellation #55525

Open theoephraim opened 3 days ago

theoephraim commented 3 days ago

What is the problem this feature will solve?

I'm working on some dev tools that require the user to set up a local DNS record in their /etc/hosts file, and I'd like to check if this lookup of some.custom.local is resolving correctly to localhost.

If I understand correctly, dns Resolver does not hit the local OS dns stack, so I must use dns.lookup, however the resolver methods have options for timeout/retries and cancellation, and lookup does not.

If successful, the dns lookup returns very quickly, yet if it fails it hangs for quite a long time while it probably retries and waits for a timeout. I understand the lookup method is doing very different things to the resolver method and this may be challenging, but nonetheless, I would like to be able to set a very short timeout or cancel the lookup if it does not succeed immediately.

What is the feature you are proposing to solve the problem?

I'd like to be able to set timeout/retry options on dns.promises.lookup, or to receive a promise that can be cancelled.

What alternatives have you considered?

Current workaround is to use Promise.race, but the process still hangs until the dns lookup finishes.

const raceResult = await Promise.race([
  sleep(10, false),
  dns.promises.lookup(devHost),
]);
if (raceResult === false) {
  throw new Error('DNS LOOKUP FAILED');
  proces.exit(1);
}
theanarkh commented 3 days ago

I can try to support cancel for dns.lookup and dns.lookupService.

climba03003 commented 3 days ago

I assume the API would look like?

const signal = AbortSignal.timeout(5000)
dns.lookup('something', { signal })
theanarkh commented 3 days ago

Yes. However, we can only cancel the dns lookup before the system sends the query request.

theoephraim commented 3 days ago

Is there a way to set the timeout?

theanarkh commented 3 days ago

I think no. We can only cancel a dns query when it is still in threadpool task queue, once it starts executing, we have no control over it.

theoephraim commented 3 days ago

There's no way to pass through a timeout to the underlying dns query?

If there's no way to cancel once it starts, then in my case it would still hang. Is there any way to get the Resolver methods to acknowledge the system host lookups /etc/hosts?

theanarkh commented 2 days ago

Resolver(c-ares) don not use /etc/hosts.