Resolvers cache answers so they don't re-query for every request. Each record carries a TTL (seconds to live). Cache a name's A values until the TTL expires, using the injected clock.
resolve(name) to serve from the cache while it's fresh; on a miss (or expiry) look up, then cache the A values with an expiry of now + ttl (use the smallest TTL among the A records)While cached, changes to the underlying zone are not visible until the entry expires, that's the whole point of a cache.
import time
class DNSResolver:
def __init__(self, zone=None, clock=time.time):
self.zone = zone if zone is not None else {}
self.clock = clock
self._rr = {}
self._cache = {} # name -> (a_values, expiry)
def _lookup(self, name, seen=None):
seen = seen or set()
if name in seen:
return ([], 0)
seen.add(name)
records = self.zone.get(name, [])
a_records = [r for r in records if r["type"] == "A"]
if a_records:
values = [r["value"] for r in a_records]
ttl = min(r["ttl"] for r in a_records)
return (values, ttl)
for r in records:
if r["type"] == "CNAME":
return self._lookup(r["value"], seen)
return ([], 0)
def resolve(self, name):
now = self.clock()
cached = self._cache.get(name)
if cached and now < cached[1]:
values = cached[0]
else:
# TODO: cache miss/expiry. Look up and cache:
# values, ttl = self._lookup(name)
# if not values: return None
# self._cache[name] = (values, now + ttl)
pass
i = self._rr.get(name, 0) % len(values)
self._rr[name] = self._rr.get(name, 0) + 1
return values[i]
The editor and the test runner need a wide screen. Open this page on a desktop browser and your progress will be waiting.
Resolvers cache answers so they don't re-query for every request. Each record carries a TTL (seconds to live). Cache a name's A values until the TTL expires, using the injected clock.
resolve(name) to serve from the cache while it's fresh; on a miss (or expiry) look up, then cache the A values with an expiry of now + ttl (use the smallest TTL among the A records)While cached, changes to the underlying zone are not visible until the entry expires, that's the whole point of a cache.
Press Run Tests or ββ© to check your solution.