dask / dask/distributed

RFC Exponential backoff in connect causing test instability?

Open
#5,847 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
1.7k
Forks
778
Avg merge
2h 50m
Merged PRs (30d)
3

Description

An interesting thing I discovered in https://github.com/dask/distributed/pull/5842 connected to test runtimes but also connect timeouts.

The tests there have a typical pattern like

```python
with popen("dask-scheduler"):
with popen("dask-worker"):
with Client("scheduler-address"):
...
```

which spawns the scheduler and a worker using the CLI as dedicated subprocesses. `popen` returns pretty fast but when it returns, the scheduler/worker is not up, yet, and ready to accept requests. The process is probably up but the dask server code is still in startup. I noticed that all of these tests run at least 2-3 seconds even if they do not do anything. I had a brief look into it and noticed that during these ~2-3 seconds, the Client is attempting to connect to the scheduler. However, since it is not up and ready to accept a connection the Client receives a "Connection refused" exception and initiates a retry with exponential backoff (see https://github.com/dask/distributed/blob/f3b0ddb6eeb928d604c0ac13e8b63b511abe3b27/distributed/comm/core.py#L279-L313). If the processes are slow to come up, that's easily a few seconds spent in backoff.

```python
# Once we're beyond ~10 attempts the backoffs *may* be very large.
# These are the *maximum* backoffs / upper_cap. The retry algorithm
# uses the below values and samples the actual backoff using ` random.uniform(0, upper_cap)`
In [1]: [0.01 * (2**attempt) for attempt in range(0, 12)]
Out[1]: [0.01, 0.02, 0.04, 0.08, 0.16, 0.32, 0.64, 1.28, 2.56, 5.12, 10.24, 20.48]
```

This primarily impacts our CLI tests which use dedicated subprocesses and wait for everything to come up and connect autonomously. Most of our tests using `utils_test.cluster` or `utils_test.gen_cluster` synchronize startup such that workers and the client are only started once the scheduler is up, such that we do not face this problem in most situations. There are a few tests outside of the CLI tests which are using a similar pattern, though, e.g. `test_variable.py::test_variable_in_task` or `test_client.py::test_reconnect`

I'm wondering
* Are there other patterns where we might run into this connect issue
* I have a strong opinion that we need a retry with backoff in production. I'm not so sure about our test suite and am wondering if disabling it for CI is something to consider

cc @crusaderky @graingert

----

Edit: Triggered a branch with hard coded instead of exponential backoff, see https://github.com/fjetter/distributed/actions/runs/1881687117

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.