For example, the request a MX query is a very very long response, how to set by example 8 seconds to stop connection and launch the error callback?
Good question. I don't think there's any timeout control exposed in dns
yet, which looks like an oversight. We should evaluate adding it.
As for a possible implementation, instead of adding another static method (like the ill-conceived dns.setServers
), I'd like to see a timeout added to option objects of lookup
and resolve*
(need to add object parameter support).
dns.lookup()
calls getaddrinfo(3)
under the hood, there is no real way to cancel that once started.
The other dns functions use c-ares. It has a configurable timeout but unfortunately that is effectively a per-process setting. It can be configured on a per-channel basis but node uses only one channel for efficiency reasons.
http://stackoverflow.com/questions/10777657/node-js-dns-lookup-how-to-set-timeout
The stop async thread realy stop the parent process?
Any chance of this getting added? It seems like such a simple feature to wait this long.
@geoffreak try https://github.com/mafintosh/dns-socket.
It seems like this is a feature request that is unlikely to be implemented, at least not without changes in upstream c-ares. I'm going to close this, but please comment (or re-open) if you think that it should stay open.
It's certainly something that should be in any DNS lib.
I'm getting requests to implement a timeout as some lookups are taking 30s+
https://www.npmjs.com/package/fcrdns
As a workaround, start a timer in parallel. If the timer expires before you get an answer back, tell the caller it timed out and ignore the answer once it does come in.
Agreed that it seems this is the only other option, but I'm under the impression it will still hold up any future lookups as it's not actually stopping.
Yes, that's true for dns.lookup()
; it calls into the C runtime library from the thread pool. dns.resolve()
and friends use minimal resources though; only a few bytes of memory.
If the timer expires before you get an answer back, tell the caller it timed out and ignore the answer once it does come in.
As I can understand 褋-ares
allows cancel requests: https://c-ares.haxx.se/ares_cancel.html. But this API isn't available in Node.js
.
Have you any plans for support cancellation for dns.resolve*
functions?
@ikokostya I think I can try to work for this feature
ares_cancel()
cancels _all_ outstanding requests, there is no way to cancel a single one.
Giving a request its own channel with ares_dup()
is _an_ option, but probably not a _good_ option. It has high overhead but what's more, since it rescans /etc/resolv.conf etc., it adds a whole new set of failure modes if the configuration changed since the application was started.
@bnoordhuis @XadillaX I鈥檝e been thinking it might make sense to expose ways to manage c-ares channels manually from JS, basically just to reduce the global state that鈥檚 inherent in having a single one per environment (then making dns.setServers
just replace the default one). And now it sounds like this issue is something where that would actually help solve a problem; what do you think?
Not opposed but depends on what the API would look like. Too much direct exposure of implementation details would make it hard to move away from c-ares if we ever needed to do that.
@addaleax I wonder how the performance it will be if we use a single channel (it means we ares_init
for each) for each request?
@XadillaX Bad, most likely. It does a lot of things: parsing config files, parsing environment variables, and so on.
It would be a very nice solution if it weren't for the overhead. Maybe someone can look into adding a less expensive version of ares_dup()
upstream. ares_clone()
, anyone?
PR for my suggestion: https://github.com/nodejs/node/issues/14518
Most helpful comment
Not opposed but depends on what the API would look like. Too much direct exposure of implementation details would make it hard to move away from c-ares if we ever needed to do that.