| OLD | NEW |
| (Empty) |
| 1 # -*- test-case-name: twisted.names.test -*- | |
| 2 # Copyright (c) 2001-2004 Twisted Matrix Laboratories. | |
| 3 # See LICENSE for details. | |
| 4 | |
| 5 | |
| 6 import time | |
| 7 | |
| 8 from zope.interface import implements | |
| 9 | |
| 10 from twisted.names import dns | |
| 11 from twisted.python import failure, log | |
| 12 from twisted.internet import interfaces, defer | |
| 13 | |
| 14 import common | |
| 15 | |
| 16 class CacheResolver(common.ResolverBase): | |
| 17 """A resolver that serves records from a local, memory cache.""" | |
| 18 | |
| 19 implements(interfaces.IResolver) | |
| 20 | |
| 21 cache = None | |
| 22 | |
| 23 def __init__(self, cache = None, verbose = 0): | |
| 24 common.ResolverBase.__init__(self) | |
| 25 | |
| 26 if cache is None: | |
| 27 cache = {} | |
| 28 self.cache = cache | |
| 29 self.verbose = verbose | |
| 30 self.cancel = {} | |
| 31 | |
| 32 | |
| 33 def __setstate__(self, state): | |
| 34 self.__dict__ = state | |
| 35 | |
| 36 now = time.time() | |
| 37 for (k, (when, (ans, add, ns))) in self.cache.items(): | |
| 38 diff = now - when | |
| 39 for rec in ans + add + ns: | |
| 40 if rec.ttl < diff: | |
| 41 del self.cache[k] | |
| 42 break | |
| 43 | |
| 44 | |
| 45 def __getstate__(self): | |
| 46 for c in self.cancel.values(): | |
| 47 c.cancel() | |
| 48 self.cancel.clear() | |
| 49 return self.__dict__ | |
| 50 | |
| 51 | |
| 52 def _lookup(self, name, cls, type, timeout): | |
| 53 now = time.time() | |
| 54 q = dns.Query(name, type, cls) | |
| 55 try: | |
| 56 when, (ans, auth, add) = self.cache[q] | |
| 57 except KeyError: | |
| 58 if self.verbose > 1: | |
| 59 log.msg('Cache miss for ' + repr(name)) | |
| 60 return defer.fail(failure.Failure(dns.DomainError(name))) | |
| 61 else: | |
| 62 if self.verbose: | |
| 63 log.msg('Cache hit for ' + repr(name)) | |
| 64 diff = now - when | |
| 65 return defer.succeed(( | |
| 66 [dns.RRHeader(str(r.name), r.type, r.cls, r.ttl - diff, r.payloa
d) for r in ans], | |
| 67 [dns.RRHeader(str(r.name), r.type, r.cls, r.ttl - diff, r.payloa
d) for r in auth], | |
| 68 [dns.RRHeader(str(r.name), r.type, r.cls, r.ttl - diff, r.payloa
d) for r in add] | |
| 69 )) | |
| 70 | |
| 71 | |
| 72 def lookupAllRecords(self, name, timeout = None): | |
| 73 return defer.fail(failure.Failure(dns.DomainError(name))) | |
| 74 | |
| 75 | |
| 76 def cacheResult(self, query, payload): | |
| 77 if self.verbose > 1: | |
| 78 log.msg('Adding %r to cache' % query) | |
| 79 | |
| 80 self.cache[query] = (time.time(), payload) | |
| 81 | |
| 82 if self.cancel.has_key(query): | |
| 83 self.cancel[query].cancel() | |
| 84 | |
| 85 s = list(payload[0]) + list(payload[1]) + list(payload[2]) | |
| 86 m = s[0].ttl | |
| 87 for r in s: | |
| 88 m = min(m, r.ttl) | |
| 89 | |
| 90 from twisted.internet import reactor | |
| 91 self.cancel[query] = reactor.callLater(m, self.clearEntry, query) | |
| 92 | |
| 93 | |
| 94 def clearEntry(self, query): | |
| 95 del self.cache[query] | |
| 96 del self.cancel[query] | |
| OLD | NEW |