Skip to content

Commit

Permalink
added spinner for long running tasks
Browse files Browse the repository at this point in the history
added spinner for long running tasks

add spinner for long running tasks
  • Loading branch information
priyanshikhetwani committed Oct 11, 2024
1 parent ee4d801 commit a0cdf44
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 21 deletions.
24 changes: 12 additions & 12 deletions cmd/image/import/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,20 +262,20 @@ pvsadm image import -n upstream-core-lon04 -b <BUCKETNAME> --object rhel-83-1003
return err
}
start := time.Now()
err = utils.PollUntil(time.Tick(2*time.Minute), time.After(opt.WatchTimeout), func() (bool, error) {
var message string
err = utils.PollUntil(time.Tick(2*time.Minute), time.After(opt.WatchTimeout), func() (string, bool, error) {
job, err := pvmclient.JobClient.Get(*jobRef.ID)
if err != nil {
return false, fmt.Errorf("image import job failed to complete, err: %v", err)
return "", false, fmt.Errorf("image import job failed to complete, err: %v", err)
}
if *job.Status.State == jobStateCompleted {
klog.V(2).Infof("Image uploaded successfully, took %s", time.Since(start).Round(time.Second))
return true, nil
return "", true, nil
}
if *job.Status.State == jobStateFailed {
return false, fmt.Errorf("image import job failed to complete, err: %v", job.Status.Message)
return "", false, fmt.Errorf("image import job failed to complete, err: %v", job.Status.Message)
}
klog.Infof("Image import is in-progress, current state: %s", *job.Status.State)
return false, nil
message = fmt.Sprintf("Image import is in-progress, current state: %s", *job.Status.State)
return message, false, nil
})
if err != nil {
return err
Expand All @@ -296,17 +296,17 @@ pvsadm image import -n upstream-core-lon04 -b <BUCKETNAME> --object rhel-83-1003
return nil
}
klog.Infof("Waiting for image %s to be active. Please wait...", opt.ImageName)
return utils.PollUntil(time.Tick(10*time.Second), time.After(opt.WatchTimeout), func() (bool, error) {
return utils.PollUntil(time.Tick(10*time.Second), time.After(opt.WatchTimeout), func() (string, bool, error) {
img, err := pvmclient.ImgClient.Get(*image.ImageID)
if err != nil {
return false, fmt.Errorf("failed to import the image, err: %v\n\nRun the command \"pvsadm get events -i %s\" to get more information about the failure", err, pvmclient.InstanceID)
return "", false, fmt.Errorf("failed to import the image, err: %v\n\nRun the command \"pvsadm get events -i %s\" to get more information about the failure", err, pvmclient.InstanceID)
}
if img.State == imageStateActive {
klog.Infof("Successfully imported the image: %s with ID: %s Total time taken: %s", *image.Name, *image.ImageID, time.Since(start).Round(time.Second))
return true, nil
return "", true, nil
}
klog.Infof("Waiting for image to be active. Current state: %s", img.State)
return false, nil
message = fmt.Sprintf("Waiting for image to be active. Current state: %s", img.State)
return message, false, nil
})
},
}
Expand Down
6 changes: 5 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
github.com/IBM/go-sdk-core/v5 v5.17.5
github.com/IBM/ibm-cos-sdk-go v1.11.1
github.com/IBM/platform-services-go-sdk v0.69.2
github.com/briandowns/spinner v1.23.1
github.com/charmbracelet/huh v0.6.0
github.com/fsnotify/fsnotify v1.7.0
github.com/go-openapi/strfmt v0.23.0
Expand All @@ -32,7 +33,7 @@ require (
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/catppuccin/go v0.2.0 // indirect
github.com/charmbracelet/bubbles v0.20.0 // indirect
github.com/charmbracelet/bubbletea v1.1.0 // indirect
github.com/charmbracelet/bubbletea v1.1.1 // indirect
github.com/charmbracelet/lipgloss v0.13.0 // indirect
github.com/charmbracelet/x/ansi v0.2.3 // indirect
github.com/charmbracelet/x/exp/strings v0.0.0-20240722160745-212f7b056ed0 // indirect
Expand All @@ -41,6 +42,7 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
github.com/fatih/color v1.16.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.5 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
Expand All @@ -67,6 +69,7 @@ require (
github.com/leodido/go-urn v1.4.0 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-localereader v0.0.1 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect
Expand All @@ -88,6 +91,7 @@ require (
golang.org/x/net v0.28.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.25.0 // indirect
golang.org/x/term v0.23.0 // indirect
golang.org/x/text v0.18.0 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
Expand Down
10 changes: 8 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,15 @@ github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiE
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/briandowns/spinner v1.23.1 h1:t5fDPmScwUjozhDj4FA46p5acZWIPXYE30qW2Ptu650=
github.com/briandowns/spinner v1.23.1/go.mod h1:LaZeM4wm2Ywy6vO571mvhQNRcWfRUnXOs0RcKV0wYKM=
github.com/catppuccin/go v0.2.0 h1:ktBeIrIP42b/8FGiScP9sgrWOss3lw0Z5SktRoithGA=
github.com/catppuccin/go v0.2.0/go.mod h1:8IHJuMGaUUjQM82qBrGNBv7LFq6JI3NnQCF6MOlZjpc=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/charmbracelet/bubbles v0.20.0 h1:jSZu6qD8cRQ6k9OMfR1WlM+ruM8fkPWkHvQWD9LIutE=
github.com/charmbracelet/bubbles v0.20.0/go.mod h1:39slydyswPy+uVOHZ5x/GjwVAFkCsV8IIVy+4MhzwwU=
github.com/charmbracelet/bubbletea v1.1.0 h1:FjAl9eAL3HBCHenhz/ZPjkKdScmaS5SK69JAK2YJK9c=
github.com/charmbracelet/bubbletea v1.1.0/go.mod h1:9Ogk0HrdbHolIKHdjfFpyXJmiCzGwy+FesYkZr7hYU4=
github.com/charmbracelet/bubbletea v1.1.1 h1:KJ2/DnmpfqFtDNVTvYZ6zpPFL9iRCRr0qqKOCvppbPY=
github.com/charmbracelet/bubbletea v1.1.1/go.mod h1:9Ogk0HrdbHolIKHdjfFpyXJmiCzGwy+FesYkZr7hYU4=
github.com/charmbracelet/huh v0.6.0 h1:mZM8VvZGuE0hoDXq6XLxRtgfWyTI3b2jZNKh0xWmax8=
github.com/charmbracelet/huh v0.6.0/go.mod h1:GGNKeWCeNzKpEOh/OJD8WBwTQjV3prFAtQPpLv+AVwU=
github.com/charmbracelet/lipgloss v0.13.0 h1:4X3PPeoWEDCMvzDvGmTajSyYPcZM4+y8sCA/SsA3cjw=
Expand Down Expand Up @@ -239,6 +241,7 @@ github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVc
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
Expand Down Expand Up @@ -424,9 +427,12 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU=
golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
Expand Down
35 changes: 29 additions & 6 deletions pkg/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (
"fmt"
"strconv"
"time"

"github.com/briandowns/spinner"
)

func FormatProcessor(proc *float64) string {
Expand Down Expand Up @@ -56,17 +58,38 @@ func RetrieveValFromMap[K comparable, V any](m map[K]V, key K) V {
// PollUntil validates if a certain condition is met at defined poll intervals.
// 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 {
func PollUntil(pollInterval, timeOut <-chan time.Time, condition func() (string, bool, error)) error {
s := spinner.New(spinner.CharSets[11], 100*time.Millisecond)
s.Color("cyan")
startTime := time.Now()

var message string
var done bool
var err error
secondTicker := time.NewTicker(1 * time.Second)
defer secondTicker.Stop()

_, done, err = condition()
if err != nil || done {
return fmt.Errorf("initial condition check failed: %w", err)
}
s.Start()
for {
select {
case <-timeOut:
return fmt.Errorf("timed out while waiting for job to complete")
case <-secondTicker.C:
s.Suffix = fmt.Sprintf(" %s (Time elapsed: %s)", message, time.Since(startTime).Round(time.Second))
case <-pollInterval:
if done, err := condition(); err != nil {
message, done, err = condition()
if err != nil || done {
s.Stop()
return err
} else if done {
return nil
}
case <-timeOut:
s.Stop()
timeoutMessage := " timed out while waiting for job to complete"
s.Suffix = timeoutMessage
return fmt.Errorf("timed out while waiting for job to complete")

}
}
}

0 comments on commit a0cdf44

Please sign in to comment.