szmarczak / cacheable-lookup

A cacheable dns.lookup(…) that respects TTL :tada:
MIT License
193 stars 29 forks source link

Rewrite main logic #31

Closed szmarczak closed 4 years ago

szmarczak commented 4 years ago

How this works?

01. cacheable.lookup('example.com', options, callback)
02. --> this.lookupAsync('example.com')
03. ----> this.query('example.com')
04. ------> await this._cache.get(hostname)
05. -----// Cached? Skip to point 09.
06. ------> this._pending[hostname]
07. -----// Is there already pending promise? Wait and skip to point 22.
08. -----// Not pending? Mark the current one as pending. Continue.
09. ------> await this.queryAndCache('localhost')
10. --------> this._hostnamesToFallback.has(hostname)
11. -------// If we know that the entry does exist locally, and
12. -------// doesn't exist on the DNS server: the native `dns.lookup(...)` is used.
13. --------> await Promise.race([resolverPromise, lookupPromise])
14. -------// If `resolverPromise` finishes first, cache it and return it.
15. -------// If `resolverPromise` throws, then point 01 throws the same.
16. -------// The current pending promise is unmarked.
17. -------//
18. -------// If `lookupPromise` finishes first, return it and skip to point 22.
19. -------// Additionally, execute an async non-blocking function to wait for
20. -------// `resolverPromise`. If it succeeds, cache it. If it doesn't succeed,
21. -------// mark the `hostname` to fall back to `dns.lookup(...)` for the next hour.
22. -------// Errors thrown by `lookupPromise` are ignored.
23. --> this.lookupAsync('example.com') // Continued.
24. ---// Filter the entries according to `options.family`.
25. ---// Filter the entries according to `options.hints` (V4MAPPED, ADDRCONFIG)
26. ---// If `cached.length === 0`, then throw ENOTFOUND.
27. ---// If options.all, return everything.
28. ---// Return the first cached element.