From: Thomas Grainger Date: Fri, 18 Mar 2022 16:57:32 +0000 (+0000) Subject: netutil: provide Resolver implementation that uses the asyncio eventloop (#3111) X-Git-Tag: v6.2.0b1~18 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=486cb2e6694e859aa7b06db7fb1b1be17e50fd2c;p=thirdparty%2Ftornado.git netutil: provide Resolver implementation that uses the asyncio eventloop (#3111) * provide Resolver implementation that uses the asyncio eventloop * switch to the DefaultLoopResolver by default --- diff --git a/maint/scripts/test_resolvers.py b/maint/scripts/test_resolvers.py index 82dec30e6..aea3a61f5 100755 --- a/maint/scripts/test_resolvers.py +++ b/maint/scripts/test_resolvers.py @@ -4,7 +4,7 @@ import socket from tornado import gen from tornado.ioloop import IOLoop -from tornado.netutil import Resolver, ThreadedResolver +from tornado.netutil import Resolver, ThreadedResolver, DefaultExecutorResolver from tornado.options import parse_command_line, define, options try: @@ -29,7 +29,7 @@ def main(): args = ['localhost', 'www.google.com', 'www.facebook.com', 'www.dropbox.com'] - resolvers = [Resolver(), ThreadedResolver()] + resolvers = [Resolver(), ThreadedResolver(), DefaultExecutorResolver()] if twisted is not None: from tornado.platform.twisted import TwistedResolver diff --git a/tornado/netutil.py b/tornado/netutil.py index 68943d825..3567b74d7 100644 --- a/tornado/netutil.py +++ b/tornado/netutil.py @@ -15,6 +15,7 @@ """Miscellaneous network utility code.""" +import asyncio import concurrent.futures import errno import os @@ -322,6 +323,7 @@ class Resolver(Configurable): The implementations of this interface included with Tornado are + * `tornado.netutil.DefaultLoopResolver` * `tornado.netutil.DefaultExecutorResolver` * `tornado.netutil.BlockingResolver` (deprecated) * `tornado.netutil.ThreadedResolver` (deprecated) @@ -332,6 +334,10 @@ class Resolver(Configurable): .. versionchanged:: 5.0 The default implementation has changed from `BlockingResolver` to `DefaultExecutorResolver`. + + .. versionchanged:: 6.2 + The default implementation has changed from `DefaultExecutorResolver` to + `DefaultLoopResolver`. """ @classmethod @@ -340,7 +346,7 @@ class Resolver(Configurable): @classmethod def configurable_default(cls) -> Type["Resolver"]: - return DefaultExecutorResolver + return DefaultLoopResolver def resolve( self, host: str, port: int, family: socket.AddressFamily = socket.AF_UNSPEC @@ -407,6 +413,25 @@ class DefaultExecutorResolver(Resolver): return result +class DefaultLoopResolver(Resolver): + """Resolver implementation using `asyncio.loop.getaddrinfo`.""" + + async def resolve( + self, host: str, port: int, family: socket.AddressFamily = socket.AF_UNSPEC + ) -> List[Tuple[int, Any]]: + # 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. + return [ + (fam, address) + for fam, _, _, _, address in await asyncio.get_running_loop().getaddrinfo( + host, port, family=family, type=socket.SOCK_STREAM + ) + ] + + class ExecutorResolver(Resolver): """Resolver implementation using a `concurrent.futures.Executor`. @@ -421,8 +446,8 @@ class ExecutorResolver(Resolver): 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. + The default `Resolver` now uses `asyncio.loop.getaddrinfo`; + use that instead of this class. """ def initialize(