- pypy3.5-5.8.0
install:
- - if [[ $TRAVIS_PYTHON_VERSION == 2* ]]; then travis_retry pip install futures mock monotonic; fi
- - if [[ $TRAVIS_PYTHON_VERSION == 'pypy' ]]; then travis_retry pip install futures mock; fi
+ - if [[ $TRAVIS_PYTHON_VERSION == 2* ]]; then travis_retry pip install mock monotonic; fi
+ - if [[ $TRAVIS_PYTHON_VERSION == 'pypy' ]]; then travis_retry pip install mock; fi
# TODO(bdarnell): pycares tests are currently disabled on travis due to ipv6 issues.
#- if [[ $TRAVIS_PYTHON_VERSION != 'pypy'* ]]; then travis_retry pip install pycares; fi
- if [[ $TRAVIS_PYTHON_VERSION != 'pypy'* ]]; then travis_retry pip install pycurl; fi
- LANG=C python $TARGET
- LANG=en_US.utf-8 python $TARGET
- if [[ $TRAVIS_PYTHON_VERSION == 3* ]]; then python -bb $TARGET; fi
- - if [[ $TRAVIS_PYTHON_VERSION != pypy* ]]; then python $TARGET --resolver=tornado.netutil.ThreadedResolver; fi
- if [[ $TRAVIS_PYTHON_VERSION == 2* ]]; then python $TARGET --httpclient=tornado.curl_httpclient.CurlAsyncHTTPClient; fi
- if [[ $TRAVIS_PYTHON_VERSION == 2* ]]; then python $TARGET --ioloop=tornado.platform.twisted.TwistedIOLoop; fi
- if [[ $TRAVIS_PYTHON_VERSION == 2* ]]; then python $TARGET --resolver=tornado.platform.twisted.TwistedResolver; fi
import stat
from tornado.concurrent import dummy_executor, run_on_executor
+from tornado import gen
from tornado.ioloop import IOLoop
from tornado.platform.auto import set_close_exec
from tornado.util import PY3, Configurable, errno_from_exception
The implementations of this interface included with Tornado are
- * `tornado.netutil.BlockingResolver`
- * `tornado.netutil.ThreadedResolver`
+ * `tornado.netutil.DefaultExecutorResolver`
+ * `tornado.netutil.BlockingResolver` (deprecated)
+ * `tornado.netutil.ThreadedResolver` (deprecated)
* `tornado.netutil.OverrideResolver`
* `tornado.platform.twisted.TwistedResolver`
* `tornado.platform.caresresolver.CaresResolver`
+
+ .. versionchanged:: 5.0
+ The default implementation has changed from `BlockingResolver` to
+ `DefaultExecutorResolver`.
"""
@classmethod
def configurable_base(cls):
@classmethod
def configurable_default(cls):
- return BlockingResolver
+ return DefaultExecutorResolver
def resolve(self, host, port, family=socket.AF_UNSPEC, callback=None):
"""Resolves an address.
pass
+def _resolve_addr(host, port, family=socket.AF_UNSPEC):
+ # On Solaris, getaddrinfo fails if the given port is not found
+ # in /etc/services and no socket type is given, so we must pass
+ # one here. The socket type used here doesn't seem to actually
+ # matter (we discard the one we get back in the results),
+ # so the addresses we return should still be usable with SOCK_DGRAM.
+ addrinfo = socket.getaddrinfo(host, port, family, socket.SOCK_STREAM)
+ results = []
+ for family, socktype, proto, canonname, address in addrinfo:
+ results.append((family, address))
+ return results
+
+
+class DefaultExecutorResolver(Resolver):
+ """Resolver implementation using `.IOLoop.run_in_executor`.
+
+ .. versionadded:: 5.0
+ """
+ @gen.coroutine
+ def resolve(self, host, port, family=socket.AF_UNSPEC):
+ result = yield IOLoop.current().run_in_executor(
+ None, _resolve_addr, host, port, family)
+ raise gen.Return(result)
+
+
class ExecutorResolver(Resolver):
"""Resolver implementation using a `concurrent.futures.Executor`.
.. versionchanged:: 5.0
The ``io_loop`` argument (deprecated since version 4.1) has been removed.
+
+ .. deprecated:: 5.0
+ The default `Resolver` now uses `.IOLoop.run_in_executor`; use that instead
+ of this class.
"""
def initialize(self, executor=None, close_executor=True):
self.io_loop = IOLoop.current()
@run_on_executor
def resolve(self, host, port, family=socket.AF_UNSPEC):
- # On Solaris, getaddrinfo fails if the given port is not found
- # in /etc/services and no socket type is given, so we must pass
- # one here. The socket type used here doesn't seem to actually
- # matter (we discard the one we get back in the results),
- # so the addresses we return should still be usable with SOCK_DGRAM.
- addrinfo = socket.getaddrinfo(host, port, family, socket.SOCK_STREAM)
- results = []
- for family, socktype, proto, canonname, address in addrinfo:
- results.append((family, address))
- return results
+ return _resolve_addr(host, port, family)
class BlockingResolver(ExecutorResolver):
The `.IOLoop` will be blocked during the resolution, although the
callback will not be run until the next `.IOLoop` iteration.
+
+ .. deprecated:: 5.0
+ The default `Resolver` now uses `.IOLoop.run_in_executor`; use that instead
+ of this class.
"""
def initialize(self):
super(BlockingResolver, self).initialize()
.. versionchanged:: 3.1
All ``ThreadedResolvers`` share a single thread pool, whose
size is set by the first one to be created.
+
+ .. deprecated:: 5.0
+ The default `Resolver` now uses `.IOLoop.run_in_executor`; use that instead
+ of this class.
"""
_threadpool = None # type: ignore
_threadpool_pid = None # type: int
py2-twistedlayered,
# Alternate Resolvers.
- {py2,py3}-full-{threadedresolver},
{py2,py3}-full-caresresolver,
# Other configurations; see comments below.
{py27,py34,py35,py36}-full: twisted
{py2,py3}: twisted
{py2,py3,py27,py34,py35,py36}-full: pycares
- # futures became standard in py32
- {py2,py27,pypy}-full: futures
# mock became standard in py33
{py2,py27,pypy,pypy3}-full: mock
# singledispatch became standard in py34.