|
| 1 | +from __future__ import annotations |
| 2 | + |
| 3 | +import asyncio |
1 | 4 | import ctypes
|
2 | 5 | import errno
|
3 | 6 | import functools
|
|
7 | 10 | import sys
|
8 | 11 | import weakref
|
9 | 12 | from ssl import SSLCertVerificationError, SSLError
|
10 |
| -from typing import ClassVar |
| 13 | +from typing import Any, ClassVar |
11 | 14 |
|
12 | 15 | from tornado import gen
|
13 | 16 |
|
|
43 | 46 | )
|
44 | 47 | from distributed.protocol.utils import pack_frames_prelude, unpack_frames
|
45 | 48 | from distributed.system import MEMORY_LIMIT
|
46 |
| -from distributed.threadpoolexecutor import ThreadPoolExecutor |
47 | 49 | from distributed.utils import ensure_ip, get_ip, get_ipv6, nbytes
|
48 | 50 |
|
49 | 51 | logger = logging.getLogger(__name__)
|
@@ -402,38 +404,31 @@ def _check_encryption(self, address, connection_args):
|
402 | 404 | )
|
403 | 405 |
|
404 | 406 |
|
405 |
| -class BaseTCPConnector(Connector, RequireEncryptionMixin): |
406 |
| - _executor: ClassVar[ThreadPoolExecutor] = ThreadPoolExecutor( |
407 |
| - 2, thread_name_prefix="TCP-Executor" |
408 |
| - ) |
409 |
| - _client: ClassVar[TCPClient] |
410 |
| - |
411 |
| - @classmethod |
412 |
| - def warmup(cls) -> None: |
413 |
| - """Pre-start threads and sockets to avoid catching them in checks for thread and |
414 |
| - fd leaks |
415 |
| - """ |
416 |
| - ex = cls._executor |
417 |
| - while len(ex._threads) < ex._max_workers: |
418 |
| - ex._adjust_thread_count() |
419 |
| - cls._get_client() |
420 |
| - |
421 |
| - @classmethod |
422 |
| - def _get_client(cls): |
423 |
| - if not hasattr(cls, "_client"): |
424 |
| - resolver = netutil.ExecutorResolver( |
425 |
| - close_executor=False, executor=cls._executor |
| 407 | +class _DefaultLoopResolver(netutil.Resolver): |
| 408 | + """ |
| 409 | + Resolver implementation using `asyncio.loop.getaddrinfo`. |
| 410 | + backport from Tornado 6.2+ |
| 411 | + https://github.com/tornadoweb/tornado/blob/3de78b7a15ba7134917a18b0755ea24d7f8fde94/tornado/netutil.py#L416-L432 |
| 412 | + """ |
| 413 | + |
| 414 | + async def resolve( |
| 415 | + self, host: str, port: int, family: socket.AddressFamily = socket.AF_UNSPEC |
| 416 | + ) -> list[tuple[int, Any]]: |
| 417 | + # On Solaris, getaddrinfo fails if the given port is not found |
| 418 | + # in /etc/services and no socket type is given, so we must pass |
| 419 | + # one here. The socket type used here doesn't seem to actually |
| 420 | + # matter (we discard the one we get back in the results), |
| 421 | + # so the addresses we return should still be usable with SOCK_DGRAM. |
| 422 | + return [ |
| 423 | + (fam, address) |
| 424 | + for fam, _, _, _, address in await asyncio.get_running_loop().getaddrinfo( |
| 425 | + host, port, family=family, type=socket.SOCK_STREAM |
426 | 426 | )
|
427 |
| - cls._client = TCPClient(resolver=resolver) |
428 |
| - return cls._client |
| 427 | + ] |
429 | 428 |
|
430 |
| - @property |
431 |
| - def client(self): |
432 |
| - # The `TCPClient` is cached on the class itself to avoid creating |
433 |
| - # excess `ThreadPoolExecutor`s. We delay creation until inside an async |
434 |
| - # function to avoid accessing an IOLoop from a context where a backing |
435 |
| - # event loop doesn't exist. |
436 |
| - return self._get_client() |
| 429 | + |
| 430 | +class BaseTCPConnector(Connector, RequireEncryptionMixin): |
| 431 | + client: ClassVar[TCPClient] = TCPClient(resolver=_DefaultLoopResolver()) |
437 | 432 |
|
438 | 433 | async def connect(self, address, deserialize=True, **connection_args):
|
439 | 434 | self._check_encryption(address, connection_args)
|
|
0 commit comments