Skip to content

Commit 945c73a

Browse files
committed
refactor: optimize pulling image progress print
Signed-off-by: thxCode <thxcode0824@gmail.com>
1 parent c3d3b19 commit 945c73a

File tree

2 files changed

+57
-9
lines changed

2 files changed

+57
-9
lines changed

gpustack_runtime/deployer/__utils__.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,3 +600,32 @@ def fnv1a_64_hex(data: bytes | str) -> str:
600600
"""
601601
hash_value = fnv1a_64(data)
602602
return f"{hash_value:016x}"
603+
604+
605+
_KiB = 1 << 10
606+
_MiB = 1 << 20
607+
_GiB = 1 << 30
608+
_TiB = 1 << 40
609+
610+
611+
def bytes_to_human_readable(size_in_bytes: int) -> str:
612+
"""
613+
Convert bytes to a human-readable string.
614+
615+
Args:
616+
size_in_bytes:
617+
The size in bytes.
618+
619+
Returns:
620+
The human-readable string.
621+
622+
"""
623+
if size_in_bytes >= _TiB:
624+
return f"{size_in_bytes / _TiB:.2f} TiB"
625+
if size_in_bytes >= _GiB:
626+
return f"{size_in_bytes / _GiB:.2f} GiB"
627+
if size_in_bytes >= _MiB:
628+
return f"{size_in_bytes / _MiB:.2f} MiB"
629+
if size_in_bytes >= _KiB:
630+
return f"{size_in_bytes / _KiB:.2f} KiB"
631+
return f"{size_in_bytes} B"

gpustack_runtime/deployer/docker.py

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
WorkloadStatusOperation,
4343
WorkloadStatusStateEnum,
4444
)
45+
from .__utils__ import _MiB, bytes_to_human_readable
4546

4647
if TYPE_CHECKING:
4748
from collections.abc import Callable, Generator
@@ -454,9 +455,12 @@ def _pull_image(self, image: str) -> docker.models.images.Image:
454455
stream=True,
455456
)
456457

458+
progress_threshold = 1
457459
progress: int = 0
460+
progress_current: int = 0
458461
layers: dict[str, int] = {}
459462
layer_progress: dict[str, int] = {}
463+
layer_progress_current: dict[str, int] = {}
460464
is_raw = sys.stdout.isatty() and logger.isEnabledFor(logging.DEBUG)
461465
for line in pull_log:
462466
line_str = (
@@ -476,6 +480,7 @@ def _pull_image(self, image: str) -> docker.models.images.Image:
476480
if log_id not in layers:
477481
layers[log_id] = len(layers)
478482
layer_progress[log_id] = 0
483+
layer_progress_current[log_id] = 0
479484
if is_raw:
480485
print("\033[E", end="")
481486
print(f"\033[{layers[log_id] + 1};0H", end="")
@@ -488,15 +493,29 @@ def _pull_image(self, image: str) -> docker.models.images.Image:
488493
p_t = log.get("progressDetail", {}).get("total")
489494
if p_c is not None and p_t is not None:
490495
layer_progress[log_id] = int(p_c * 100 // p_t)
491-
p_diff = (
492-
sum(layer_progress.values())
493-
* 100
494-
// (len(layer_progress) * 100)
495-
- progress
496-
)
497-
if p_diff >= 10:
498-
progress += 10
499-
logger.info(f"Pulling image {image}: {progress}%")
496+
p_diff = (
497+
sum(layer_progress.values())
498+
* 100
499+
// (len(layer_progress) * 100)
500+
- progress
501+
)
502+
if p_diff >= progress_threshold:
503+
progress += progress_threshold
504+
progress_threshold = min(5, progress_threshold + 1)
505+
logger.info(f"Pulling image {image}: {progress}%")
506+
elif p_c is not None:
507+
layer_progress_current[log_id] = p_c
508+
p_c_total = sum(layer_progress_current.values())
509+
p_diff = p_c_total - progress_current
510+
if p_diff >= progress_threshold * _MiB:
511+
progress_current = p_c_total
512+
progress_threshold = min(
513+
200,
514+
progress_threshold + 2,
515+
)
516+
logger.info(
517+
f"Pulling image {image}: {bytes_to_human_readable(p_c_total)}",
518+
)
500519
elif is_raw:
501520
print(f"{log_id}: {log['status']}", flush=True)
502521

0 commit comments

Comments
 (0)