diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index 94c28ecc..4879ef3b 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -18,6 +18,8 @@ import ( "fmt" "strconv" "time" + + "github.com/charmbracelet/huh/spinner" ) func FormatProcessor(proc *float64) string { @@ -57,15 +59,47 @@ func RetrieveValFromMap[K comparable, V any](m map[K]V, key K) V { // If a timeout is reached, an associated error is returned to the caller. // condition contains the use-case specific code that returns true when a certain condition is achieved. func PollUntil(pollInterval, timeOut <-chan time.Time, condition func() (bool, error)) error { + s := spinner.New() + // Variable to store the time taken for polling, rounded to the nearest second. + time_taken := time.Since(time.Now()).Round(time.Second) + action := func() { + lastMessage := "" + ticker := time.NewTicker(1000 * time.Millisecond) + done := make(chan bool) + now := time.Now() + // Goroutine to keep updating the spinner with polling status. + go func() { + for { + select { + case <-done: + // Stop the goroutine when done is signaled. + return + case <-ticker.C: + // Update the spinner's title with the elapsed time. + lastMessage = fmt.Sprintf("Condition not yet met. Continuing to poll... %s", time.Since(now).Round(time.Second)) + time_taken = time.Since(now).Round(time.Second) + s.Title(lastMessage) + } + } + }() + // Simulate polling for 16 seconds. + time.Sleep(16000 * time.Millisecond) + ticker.Stop() + done <- true + } + for { select { case <-timeOut: return fmt.Errorf("timed out while waiting for job to complete") case <-pollInterval: - if done, err := condition(); err != nil { + if done, err := condition(); done || err != nil { return err - } else if done { - return nil + } else { + // Start the spinner and polling action. + s.Title("Starting polling...").Action(action).Run() + // Print the time taken to complete polling. + fmt.Println("Polling completed in: ", time_taken) } } }