deno icon indicating copy to clipboard operation
deno copied to clipboard

`node:dns` doesn't support `timeout` options

Open gnattu opened this issue 2 years ago • 4 comments

Describe the bug I'm trying to use deno for DNS health check which will respond to a DNS failure. But, I found that the node/dns module handles dns failure poorly, which takes around 15s to report a resolve failure, and this is too slow for my use case. I tried to use a custom resolver like below:

const resolver = new DNS.promises.Resolver({ timeout: 1000, tries: 1 })

But a failure is still taking around 15 seconds to report. Both the callback and the promise api has this issue.

Steps to Reproduce

  • Create a js file with the following contents:
import * as DNS from 'https://deno.land/[email protected]/node/dns.ts'
const resolver = new DNS.promises.Resolver({ timeout: 1000, tries: 1 })
resolver.setServers(['127.0.0.1']) // You should not have real DNS server on this machine
try {
    await resolver.resolve4('mirror.archlinuxarm.org')
  } catch (e) {
    console.log('dns-fail')
}
  • Run it with deno: deno run --allow-all index.js

  • The dns-fail will print after 15 seconds.

Expected behavior

The dns-fail message should be printed much earlier. In this case, around 1s as the timeout is set this way.

The behavior of original nodejs is slightly different: the promise will be rejected immediately with ECONNREFUSED . But for my use case a timeout is good enough.

Environment

  • OS: macOS 13.2
  • deno version: 1.30.0
  • std version: 0.175.0

gnattu avatar Feb 02 '23 11:02 gnattu

This is definitely a bug with std/node but I would like to point out that you probably shouldn't be using std/node/dns and instead be using something like Deno.resolveDns()

lino-levan avatar Feb 12 '23 05:02 lino-levan

you probably shouldn't be using std/node/dns and instead be using something like Deno.resolveDns()

Oh I see, do you know any way that I can set a custom duration for timeout using Deno.resolveDns? The Deno.ResolveDnsOptions does not have an option for timeout and that's why I was looking at std/node/dns which provides customizable timeout in its ResolverOptions

gnattu avatar Feb 13 '23 06:02 gnattu

do you know any way that I can set a custom duration for timeout

You could use std/async/deadline to create a custom timeout since it seems like Deno.resolveDns() doesn't support the AbortController API.

lino-levan avatar Feb 13 '23 07:02 lino-levan

you probably shouldn't be using std/node/dns and instead be using something like Deno.resolveDns()

Oh I see, do you know any way that I can set a custom duration for timeout using Deno.resolveDns? The Deno.ResolveDnsOptions does not have an option for timeout and that's why I was looking at std/node/dns which provides customizable timeout in its ResolverOptions

You can use this code:

await Deno.resolveDns("wikipedia.org", "A", { signal: AbortSignal.timeout(500), nameServer: { ipAddr: "9.9.9.9" } } )

I came across this issue when I was looking for the same option.

juanfra684 avatar Oct 26 '24 23:10 juanfra684

It appears that the timeout options in node:dns is now supported in Deno 2.1.8.

bartlomieju avatar Feb 03 '25 00:02 bartlomieju