| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162 |
- # Just like ThreadedResolver, but doesn't suck
- #
- # The contents of this file are subject to the Python Software Foundation
- # License Version 2.3 (the License). You may not copy or use this file, in
- # either source code or executable form, except in compliance with the License.
- # You may obtain a copy of the License at http://www.python.org/license.
- #
- # Software distributed under the License is distributed on an AS IS basis,
- # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- # for the specific language governing rights and limitations under the
- # License.
- #
- # by Greg Hazel
- import socket
- import operator
- from twisted.internet import error, defer, threads
- from twisted.python import failure
- class SaneThreadedResolver:
- # I won't do this. Zope.interface sucks.
- #implements(IResolverSimple)
- def __init__(self, reactor):
- self.reactor = reactor
- self._runningQueries = {}
- def _fail(self, name, err):
- err = error.DNSLookupError("address %r not found: %s" % (name, err))
- return failure.Failure(err)
- def _checkTimeout(self, result, name, userDeferred):
- if userDeferred in self._runningQueries:
- cancelCall = self._runningQueries.pop(userDeferred)
- cancelCall.cancel()
- if userDeferred.called:
- return
- if isinstance(result, failure.Failure):
- userDeferred.errback(self._fail(name, result.getErrorMessage()))
- else:
- userDeferred.callback(result)
- def _doGetHostByName(self, name, onStart):
- self.reactor.callFromThread(onStart)
- return socket.gethostbyname(name)
- def getHostByName(self, name, timeout = (1, 3, 11, 45)):
- if timeout:
- timeoutDelay = reduce(operator.add, timeout)
- else:
- timeoutDelay = 60
- userDeferred = defer.Deferred()
- def _onStart():
- cancelCall = self.reactor.callLater(
- timeoutDelay, self._checkTimeout,
- self._fail(name, "timeout error"), name, userDeferred)
- self._runningQueries[userDeferred] = cancelCall
- lookupDeferred = threads.deferToThread(self._doGetHostByName, name, _onStart)
- lookupDeferred.addBoth(self._checkTimeout, name, userDeferred)
- return userDeferred
|