def listen(addr, handle_comm, deserialize=True, **kwargs): """ Create a listener object with the given parameters. When its ``start()`` method is called, the listener will listen on the given address (a URI such as ``tcp://0.0.0.0``) and call *handle_comm* with a ``Comm`` object for each incoming connection. *handle_comm* can be a regular function or a coroutine. """ try: scheme, loc = parse_address(addr, strict=True) except ValueError: if kwargs.get("ssl_context"): addr = "tls://" + addr else: addr = "tcp://" + addr scheme, loc = parse_address(addr, strict=True) backend = registry.get_backend(scheme) return backend.get_listener(loc, handle_comm, deserialize, **kwargs)
async def _create_listeners(session_state, nworkers, rank): assert session_state["loop"] is asyncio.get_event_loop() assert "nworkers" not in session_state session_state["nworkers"] = nworkers assert "rank" not in session_state session_state["rank"] = rank async def server_handler(ep): peer_rank = await ep.read() session_state["eps"][peer_rank] = ep # We listen on the same protocol and address as the worker address protocol, address = parse_address(session_state["worker"].address) address = parse_host_port(address)[0] address = unparse_address(protocol, address) session_state["lf"] = distributed.comm.listen(address, server_handler) await session_state["lf"].start() return session_state["lf"].listen_address
def parse_it(x): return parse_host_port(parse_address(x)[1])
async def connect( addr, timeout=None, deserialize=True, handshake_overrides=None, **connection_args ): """ Connect to the given address (a URI such as ``tcp://127.0.0.1:1234``) and yield a ``Comm`` object. If the connection attempt fails, it is retried until the *timeout* is expired. """ if timeout is None: timeout = dask.config.get("distributed.comm.timeouts.connect") timeout = parse_timedelta(timeout, default="seconds") scheme, loc = parse_address(addr) backend = registry.get_backend(scheme) connector = backend.get_connector() comm = None start = time() def time_left(): deadline = start + timeout return max(0, deadline - time()) backoff_base = 0.01 attempt = 0 # Prefer multiple small attempts than one long attempt. This should protect # primarily from DNS race conditions # gh3104, gh4176, gh4167 intermediate_cap = timeout / 5 active_exception = None while time_left() > 0: try: comm = await asyncio.wait_for( connector.connect(loc, deserialize=deserialize, **connection_args), timeout=min(intermediate_cap, time_left()), ) break except FatalCommClosedError: raise # Note: CommClosed inherits from OSError except (asyncio.TimeoutError, OSError) as exc: active_exception = exc # As descibed above, the intermediate timeout is used to distributed # initial, bulk connect attempts homogeneously. In particular with # the jitter upon retries we should not be worred about overloading # any more DNS servers intermediate_cap = timeout # FullJitter see https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/ upper_cap = min(time_left(), backoff_base * (2**attempt)) backoff = random.uniform(0, upper_cap) attempt += 1 logger.debug( "Could not connect to %s, waiting for %s before retrying", loc, backoff ) await asyncio.sleep(backoff) else: raise OSError( f"Timed out trying to connect to {addr} after {timeout} s" ) from active_exception local_info = { **comm.handshake_info(), **(handshake_overrides or {}), } try: # This would be better, but connections leak if worker is closed quickly # write, handshake = await asyncio.gather(comm.write(local_info), comm.read()) handshake = await asyncio.wait_for(comm.read(), time_left()) await asyncio.wait_for(comm.write(local_info), time_left()) except Exception as exc: with suppress(Exception): await comm.close() raise OSError( f"Timed out during handshake while connecting to {addr} after {timeout} s" ) from exc comm.remote_info = handshake comm.remote_info["address"] = comm._peer_addr comm.local_info = local_info comm.local_info["address"] = comm._local_addr comm.handshake_options = comm.handshake_configuration( comm.local_info, comm.remote_info ) return comm