Skip to content

Commit a92a527

Browse files
author
Bret Wortman
committed
Add delayed 'Gathering status...' message for long-running status operations
- Shows 'Gathering status...' after 5 seconds if status gathering is still in progress - Uses threading to avoid blocking the main operation - Automatically clears the message when gathering completes - Respects --porcelain mode (no message in machine-readable output) - Robust error handling ensures timer cleanup in all cases - Improves UX when checking status across many repositories
1 parent 14f6e6a commit a92a527

1 file changed

Lines changed: 58 additions & 8 deletions

File tree

  • packages/deepfreeze-core/deepfreeze_core/actions

packages/deepfreeze-core/deepfreeze_core/actions/status.py

Lines changed: 58 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
import json
66
import logging
7+
import threading
8+
import time
79

810
from elasticsearch8 import Elasticsearch
911
from rich.console import Console
@@ -401,24 +403,60 @@ def do_dry_run(self) -> None:
401403
self.loggit.info("DRY-RUN MODE. No changes will be made.")
402404
self.do_action()
403405

406+
def _gather_status_info(self):
407+
"""
408+
Gather all status information. This method contains the potentially slow operations.
409+
410+
:return: tuple of (repos, thaw_requests, buckets, ilm_policies)
411+
:rtype: tuple
412+
"""
413+
# Load settings
414+
self._load_settings()
415+
416+
# Gather all status information
417+
repos = self._get_repositories_status()
418+
thaw_requests = self._get_thaw_requests()
419+
buckets = self._get_buckets_info()
420+
ilm_policies = self._get_ilm_policies()
421+
422+
return repos, thaw_requests, buckets, ilm_policies
423+
404424
def do_action(self) -> None:
405425
"""
406426
Display status information about deepfreeze.
427+
Shows a "Gathering status..." message if the operation takes longer than 5 seconds.
407428
408429
:return: None
409430
:rtype: None
410431
"""
411432
self.loggit.debug("Starting Status action")
412433

413-
try:
414-
# Load settings
415-
self._load_settings()
434+
# Setup for delayed status message
435+
status_message_shown = threading.Event()
436+
gather_completed = threading.Event()
437+
438+
def show_status_message():
439+
"""Show gathering message if operation takes too long."""
440+
if not gather_completed.wait(5.0): # Wait 5 seconds
441+
if not status_message_shown.is_set() and not self.porcelain:
442+
status_message_shown.set()
443+
self.console.print("[dim]Gathering status...[/dim]")
444+
445+
# Start the delayed message timer
446+
timer_thread = threading.Thread(target=show_status_message, daemon=True)
447+
timer_thread.start()
416448

417-
# Gather all status information
418-
repos = self._get_repositories_status()
419-
thaw_requests = self._get_thaw_requests()
420-
buckets = self._get_buckets_info()
421-
ilm_policies = self._get_ilm_policies()
449+
try:
450+
# Gather all status information (potentially slow operations)
451+
repos, thaw_requests, buckets, ilm_policies = self._gather_status_info()
452+
453+
# Signal that gathering is complete
454+
gather_completed.set()
455+
456+
# Clear the status message if it was shown
457+
if status_message_shown.is_set() and not self.porcelain:
458+
# Move cursor up one line and clear it to remove the "Gathering status..." message
459+
self.console.print("\033[1A\033[K", end="")
422460

423461
# Display output
424462
if self.porcelain:
@@ -427,6 +465,7 @@ def do_action(self) -> None:
427465
self._display_rich(repos, thaw_requests, buckets, ilm_policies)
428466

429467
except MissingIndexError:
468+
gather_completed.set() # Make sure to signal completion even on error
430469
if self.porcelain:
431470
print(
432471
json.dumps(
@@ -437,6 +476,9 @@ def do_action(self) -> None:
437476
)
438477
)
439478
else:
479+
# Clear status message if shown
480+
if status_message_shown.is_set():
481+
self.console.print("\033[1A\033[K", end="")
440482
self.console.print(
441483
Panel(
442484
f"[bold]Status index [cyan]{STATUS_INDEX}[/cyan] does not exist.[/bold]\n\n"
@@ -450,6 +492,7 @@ def do_action(self) -> None:
450492
raise
451493

452494
except MissingSettingsError:
495+
gather_completed.set() # Make sure to signal completion even on error
453496
if self.porcelain:
454497
print(
455498
json.dumps(
@@ -460,6 +503,9 @@ def do_action(self) -> None:
460503
)
461504
)
462505
else:
506+
# Clear status message if shown
507+
if status_message_shown.is_set():
508+
self.console.print("\033[1A\033[K", end="")
463509
self.console.print(
464510
Panel(
465511
"[bold]Settings document not found in status index.[/bold]\n\n"
@@ -475,9 +521,13 @@ def do_action(self) -> None:
475521
raise
476522

477523
except Exception as e:
524+
gather_completed.set() # Make sure to signal completion even on error
478525
if self.porcelain:
479526
print(json.dumps({"error": "unexpected", "message": str(e)}))
480527
else:
528+
# Clear status message if shown
529+
if status_message_shown.is_set():
530+
self.console.print("\033[1A\033[K", end="")
481531
self.console.print(
482532
Panel(
483533
f"[bold]An unexpected error occurred[/bold]\n\n"

0 commit comments

Comments
 (0)