SpecCluster._correct_state_internal closes workers with Nanny's default 5s timeout; shutdown often fails on LocalCluster(processes=True)
評価
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 初心者へのやさしさ
- 48/100
- issue の種類
- バグ
- 明瞭さ
- おおむね明確
- 活発さ
- 静か
- 技術スタック
- python
調査の方向性
トレースバックは distributed/deploy/spec.py と SpecCluster._correct_state_internal() を指している。まず、完了した futures を保持したまま、LocalCluster(processes=True) と client.shutdown() のサンプルで問題を再現する。次に retirement と AMM の経路を追跡し、その後、クラスター全体の teardown によって不要な retirement 処理が回避され、TimeoutError が発生しなくなることを示す回帰チェックを確立する。
索引モデルが issue の本文から書いたものです。
説明
TimeoutError during client.shutdown() due to unnecessary AMM retirement when futures are not explicitly released
Description
When shutting down a dedicated LocalCluster via client.shutdown() after batch processing is complete, Dask still executes the full graceful worker retirement path (retire_workers + Active Memory Manager replication/drop), even though all workers are being removed and the results are no longer needed.
If the client has not released its futures first, completed task data remains in the scheduler's state memory on the workers. During shutdown, the AMM attempts to replicate or drop those keys across workers that are simultaneously shutting down. This causes unnecessary network/memory overhead and slows down worker teardown. Consequently, this can exceed the Nanny’s default process.join timeout (~4s) and surface as a TimeoutError / Tornado ERROR log during SpecCluster._correct_state_internal().
Releasing all client-held keys before cluster.close() avoids the problem in practice, which suggests the current shutdown path is doing redundant work that a full-cluster teardown should not require.
Sample Code from My Project
Create cluster and client
cls.cluster = LocalCluster(
name="cluster",
n_workers=cls.n_workers,
threads_per_worker=cls.threads_per_worker,
memory_limit=0,
dashboard_address=dashboard_address
)
cls.client = Client(
name="client",
address=cls.cluster,
direct_to_workers=True
)
Shutdown
@classmethod
def system_teardown(cls):
with suppress(Exception):
cls.client.shutdown()
Error Stack Trace
Occasionally, the following error occurs during shutdown:
2026-06-10 14:56:47,407 - tornado.application - ERROR - Exception in callback functools.partial(<bound method IOLoop._discard_future_result of <tornado.platform.asyncio.AsyncIOMainLoop object at 0x00000288583A1D30>>, <Task finished name='Task-1174981' coro=<Spec Cluster._correct_state_internal() done, defined at .venvLibsite-packagesdistributeddeployspec.py:346> exception=TimeoutError()>)
Traceback (most recent call last):
File ".venvLibsite-packagesdistributedutils.py", line 1910, in wait_for
return await fut
asyncio.exceptions.CancelledError
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File ".venvLibsite-packagestornadoioloop.py", line 758, in _run_callback
ret = callback()
File ".venvLibsite-packagestornadoioloop.py", line 782, in _discard_future_result
future.result()
TimeoutError
Root Cause Analysis
When client.shutdown() is called without prior key release, completed task data remains in the scheduler's state memory on the workers. During the shutdown sequence, the Active Memory Manager (AMM) attempts to replicate or drop these keys across workers that are concurrently being torn down. This triggers unnecessary network/memory operations and significantly slows down the worker teardown process. Ultimately, this exceeds the Nanny’s default process.join timeout (~4s), resulting in a TimeoutError within SpecCluster._correct_state_internal().
Suggestions / Recommendations
Optimize Full-Cluster Teardown: Consider bypassing or short-circuiting the AMM retirement logic (retire_workers, data replication/drop) when a full-cluster teardown is initiated via client.shutdown(). Since all workers are being removed anyway, preserving or migrating their data is redundant.
Auto-Release on Shutdown: Alternatively, automatically release all client-held keys before initiating the shutdown sequence to prevent the AMM from acting on stale future references.
Documentation: In the meantime, it might be helpful to document this behavior and recommend users explicitly release their futures (e.g., via client.release() or iterating over client.futures) before calling shutdown() as a best practice.
Thanks!
- 主要言語
- Python
- スター
- 1.7k
- フォーク
- 781
- PR マージ指標
- 30日以内にマージされた PR はありません
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
dask/distributed のほかの issue
-
needs triage
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
dask/distributed#9366 ·
-
Scipy's spmatrix deprecation keeps the Upstream nightly red after #9351 — all 14 test_serialize_scipy_sparse cases fail対応中かも このイシューにリンクされたプルリクエストがオープン中、またはマージ済みです。 オープンneeds triage
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
dask/distributed#9353 · コメント 1 件 ·
-
documentation
難易度 1/5 1〜3時間 初心者へのやさしさ 82/100
dask/distributed#8304 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 74/100
dask/distributed#4816 · コメント 2 件 ·
-
Client.scheduler_info needs better documentation対応中かも @nil68657 が 13 日前に担当しました。 オープンdocumentation good first issue
難易度 2/5 1〜3時間 初心者へのやさしさ 74/100
dask/distributed#2378 · コメント 2 件 ·
dask/distributed の issue をすべて見る
似ている issue
-
intake mcp-intake needs-ac needs-human-review priority:medium
難易度 2/5 1〜3時間 初心者へのやさしさ 67/100
Ikalus1988/MisakaNet#3848 · コメント 2 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 1/5 1時間未満 初心者へのやさしさ 75/100
521xueweihan/HelloGitHub#4105 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
igormcsouza/bookloud#54 ·
-
難易度 1/5 1時間未満 初心者へのやさしさ 90/100
aws-samples/sample-per-model-bedrock#526 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
ok-oldking/ok-wuthering-waves#1802 ·
メンテナーはふだん 2 日以内に返信