Main display loop running in background thread.
(self)
| 63 | self._display_thread.join(timeout=1.0) |
| 64 | |
| 65 | def _display_loop(self) -> None: |
| 66 | """Main display loop running in background thread.""" |
| 67 | spinner_index = 0 |
| 68 | # Initialize to current time so first status only shows after 5s of activity |
| 69 | # This prevents duplicate "Running:" messages from appearing immediately |
| 70 | last_status_time = time.time() |
| 71 | status_interval = ( |
| 72 | 5 # Show status every 5 seconds (reduced noise for short tasks) |
| 73 | ) |
| 74 | last_printed_message: Optional[str] = None # Track last message to avoid spam |
| 75 | |
| 76 | while not self._stop_event.is_set(): |
| 77 | try: |
| 78 | # Wait for monitoring to start, or exit if stopped |
| 79 | if not self.group._status_monitoring_active: |
| 80 | time.sleep(0.1) |
| 81 | continue |
| 82 | |
| 83 | current_time = time.time() |
| 84 | group_status = self.group.get_status() |
| 85 | |
| 86 | # Show periodic status updates instead of continuous display |
| 87 | if current_time - last_status_time >= status_interval: |
| 88 | running_count = sum(1 for p in group_status.processes if p.is_alive) |
| 89 | completed_count = group_status.completed_processes |
| 90 | |
| 91 | if running_count > 0: |
| 92 | # Show a clean status update (no spinner noise) |
| 93 | running_names = [ |
| 94 | p.name for p in group_status.processes if p.is_alive |
| 95 | ] |
| 96 | running_list = ( |
| 97 | ", ".join(running_names) if running_names else "none" |
| 98 | ) |
| 99 | total = group_status.total_processes |
| 100 | # For single item, omit counter; for multiple, use 1-indexed current position |
| 101 | if total == 1: |
| 102 | status_msg = f" Running: {running_list}" |
| 103 | else: |
| 104 | # Show 1-indexed "current/total" (e.g., [1/3] when first is running) |
| 105 | current = completed_count + 1 |
| 106 | status_msg = ( |
| 107 | f" [{current}/{total}] Running: {running_list}" |
| 108 | ) |
| 109 | |
| 110 | # Only print if status changed to avoid spam |
| 111 | if status_msg != last_printed_message: |
| 112 | print(status_msg, flush=True) |
| 113 | last_printed_message = status_msg |
| 114 | |
| 115 | last_status_time = current_time |
| 116 | |
| 117 | spinner_index = (spinner_index + 1) % 4 |
| 118 | time.sleep(1.0) # Check every second but only print every 5 seconds |
| 119 | |
| 120 | except KeyboardInterrupt as ki: |
| 121 | handle_keyboard_interrupt(ki) |
| 122 | raise |
nothing calls this directly
no test coverage detected