-
-
Notifications
You must be signed in to change notification settings - Fork 719
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support dumping cluster state to URL (#5863)
- Loading branch information
Showing
7 changed files
with
374 additions
and
110 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
"Utilities for generating and analyzing cluster dumps" | ||
|
||
from __future__ import annotations | ||
|
||
from typing import IO, Any, Awaitable, Callable, Literal | ||
|
||
import fsspec | ||
import msgpack | ||
|
||
from distributed.compatibility import to_thread | ||
|
||
|
||
def _tuple_to_list(node): | ||
if isinstance(node, (list, tuple)): | ||
return [_tuple_to_list(el) for el in node] | ||
elif isinstance(node, dict): | ||
return {k: _tuple_to_list(v) for k, v in node.items()} | ||
else: | ||
return node | ||
|
||
|
||
async def write_state( | ||
get_state: Callable[[], Awaitable[Any]], | ||
url: str, | ||
format: Literal["msgpack", "yaml"], | ||
**storage_options: dict[str, Any], | ||
) -> None: | ||
"Await a cluster dump, then serialize and write it to a path" | ||
if format == "msgpack": | ||
mode = "wb" | ||
suffix = ".msgpack.gz" | ||
if not url.endswith(suffix): | ||
url += suffix | ||
writer = msgpack.pack | ||
elif format == "yaml": | ||
import yaml | ||
|
||
mode = "w" | ||
suffix = ".yaml" | ||
if not url.endswith(suffix): | ||
url += suffix | ||
|
||
def writer(state: dict, f: IO): | ||
# YAML adds unnecessary `!!python/tuple` tags; convert tuples to lists to avoid them. | ||
# Unnecessary for msgpack, since tuples and lists are encoded the same. | ||
yaml.dump(_tuple_to_list(state), f) | ||
|
||
else: | ||
raise ValueError( | ||
f"Unsupported format {format!r}. Possible values are 'msgpack' or 'yaml'." | ||
) | ||
|
||
# Eagerly open the file to catch any errors before doing the full dump | ||
# NOTE: `compression="infer"` will automatically use gzip via the `.gz` suffix | ||
with fsspec.open(url, mode, compression="infer", **storage_options) as f: | ||
state = await get_state() | ||
# Write from a thread so we don't block the event loop quite as badly | ||
# (the writer will still hold the GIL a lot though). | ||
await to_thread(writer, state, f) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.