diff --git a/lib/dns.js b/lib/dns.js index aec953aaf53a35..5a1a0255db6cbe 100644 --- a/lib/dns.js +++ b/lib/dns.js @@ -31,7 +31,7 @@ const cares = internalBinding('cares_wrap'); const { isIP } = require('internal/net'); const { customPromisifyArgs } = require('internal/util'); const errors = require('internal/errors'); -const { setInterval } = require('timers'); +const { setTimeout, unref } = require('timers'); const { bindDefaultResolver, setDefaultResolver, @@ -134,19 +134,47 @@ function onlookupall(err, addresses) { } } +function cleanDnsCache() { + for (const key in dnsCache) { + delete dnsCache[key]; + } +} + +function scheduleCleanup() { + if (cleanupTimeout) { + return; + } + + cleanupTimeout = setTimeout(() => { + cleanDnsCache(); + cleanupTimeout = null; + }, 1000).ref(); +} + +function addDnsEntry(cacheKey, address, family) { + dnsCache[cacheKey] = { + address, + family, + timestamp: DateNow(), + }; + + scheduleCleanup(); + + return dnsCache[cacheKey]; +} // Easy DNS A/AAAA look up // lookup(hostname, [options,] callback) const validFamilies = [0, 4, 6]; const dnsCache = { __proto__: null }; +const { DateNow } = primordials; +let cleanupTimeout = null; function lookup(hostname, options, callback) { let hints = 0; let family = 0; let all = false; let verbatim = getDefaultVerbatim(); - const cacheKey = `${hostname}_${family || 'default'}`; - const cachedResult = dnsCache[cacheKey]; // Parse arguments if (hostname) { @@ -196,12 +224,6 @@ function lookup(hostname, options, callback) { } } - const { DateNow } = primordials; - if (cachedResult && DateNow() - cachedResult.timestamp < 1000) { - callback(null, cachedResult.address, cachedResult.family); - return {}; - } - if (!hostname) { emitInvalidHostnameWarning(hostname); if (all) { @@ -223,14 +245,19 @@ function lookup(hostname, options, callback) { return {}; } + const cacheKey = `${hostname}_${family || 'default'}`; + const cachedResult = dnsCache[cacheKey]; + + if (cachedResult && DateNow() - cachedResult.timestamp < 1000) { + callback(null, cachedResult.address, cachedResult.family); + return {}; + } + + const req = new GetAddrInfoReqWrap(); req.callback = (error, address, family) => { if (!error) { - dnsCache[cacheKey] = { - address, - family, - timestamp: DateNow(), - }; + addDnsEntry(cacheKey, address, family); } callback(error, address, family); }; @@ -257,17 +284,6 @@ function lookup(hostname, options, callback) { return req; } -// DNS cache checks every 1 second -setInterval(() => { - const { DateNow } = primordials; - const currentTime = DateNow(); - for (const key in dnsCache) { - if (currentTime - dnsCache[key].timestamp >= 1000) { - delete dnsCache[key]; - } - } -}, 1000).unref(); - ObjectDefineProperty(lookup, customPromisifyArgs, { __proto__: null, value: ['address', 'family'], enumerable: false });