Skip to content

Commit

Permalink
progress: more options for speed, and backward-compatible defaults (#225
Browse files Browse the repository at this point in the history
)
  • Loading branch information
jedib0t committed Sep 3, 2022
1 parent ab70b68 commit fb89930
Show file tree
Hide file tree
Showing 7 changed files with 171 additions and 152 deletions.
9 changes: 4 additions & 5 deletions cmd/demo-progress/demo.go
Expand Up @@ -18,9 +18,9 @@ var (
flagHidePercentage = flag.Bool("hide-percentage", false, "Hide the progress percent?")
flagHideTime = flag.Bool("hide-time", false, "Hide the time taken?")
flagHideValue = flag.Bool("hide-value", false, "Hide the tracker value?")
flagHideSpeed = flag.Bool("hide-speed", false, "Hide the tracker speed?")
flagHideSpeedOverall = flag.Bool("hide-speed-overall", false, "Hide the overall tracker speed?")
flagNumTrackers = flag.Int("num-trackers", 13, "Number of Trackers")
flagShowSpeed = flag.Bool("show-speed", false, "Show the tracker speed?")
flagShowSpeedOverall = flag.Bool("show-speed-overall", false, "Show the overall tracker speed?")
flagRandomFail = flag.Bool("rnd-fail", false, "Introduce random failures in tracking")
flagRandomLogs = flag.Bool("rnd-logs", false, "Output random logs in the middle of tracking")

Expand Down Expand Up @@ -115,15 +115,14 @@ func main() {
pw.SetUpdateFrequency(time.Millisecond * 100)
pw.Style().Colors = progress.StyleColorsExample
pw.Style().Options.PercentFormat = "%4.1f%%"
pw.Style().Options.SpeedOverallFormatter = progress.FormatNumber
pw.Style().Visibility.ETA = !*flagHideETA
pw.Style().Visibility.ETAOverall = !*flagHideETAOverall
pw.Style().Visibility.Percentage = !*flagHidePercentage
pw.Style().Visibility.Speed = *flagShowSpeed
pw.Style().Visibility.SpeedOverall = *flagShowSpeedOverall
pw.Style().Visibility.Time = !*flagHideTime
pw.Style().Visibility.TrackerOverall = !*flagHideOverallTracker
pw.Style().Visibility.Value = !*flagHideValue
pw.Style().Visibility.Speed = !*flagHideSpeed
pw.Style().Visibility.SpeedOverall = !*flagHideSpeedOverall

// call Render() in async mode; yes we don't have any trackers at the moment
go pw.Render()
Expand Down
Binary file modified progress/images/demo.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions progress/progress.go
Expand Up @@ -267,6 +267,9 @@ func (p *Progress) Style() *Style {
func (p *Progress) initForRender() {
// pick a default style
p.Style()
if p.style.Options.SpeedOverallFormatter == nil {
p.style.Options.SpeedOverallFormatter = FormatNumber
}

// reset the signals
p.done = make(chan bool, 1)
Expand Down
87 changes: 46 additions & 41 deletions progress/render.go
Expand Up @@ -323,8 +323,9 @@ func (p *Progress) renderTrackerStats(out *strings.Builder, t *Tracker, hint ren
var outStats strings.Builder
outStats.WriteString(" [")

p.renderTrackerSpeed(&outStats, t, hint)

if p.style.Options.SpeedPosition == PositionLeft {
p.renderTrackerStatsSpeed(&outStats, t, hint)
}
if !hint.hideValue {
outStats.WriteString(p.style.Colors.Value.Sprint(t.Units.Sprint(t.Value())))
}
Expand All @@ -334,12 +335,55 @@ func (p *Progress) renderTrackerStats(out *strings.Builder, t *Tracker, hint ren
if !hint.hideTime {
p.renderTrackerStatsTime(&outStats, t, hint)
}
if p.style.Options.SpeedPosition == PositionRight {
p.renderTrackerStatsSpeed(&outStats, t, hint)
}
outStats.WriteRune(']')

out.WriteString(p.style.Colors.Stats.Sprint(outStats.String()))
}
}

func (p *Progress) renderTrackerStatsSpeed(out *strings.Builder, t *Tracker, hint renderHint) {
if hint.isOverallTracker && !p.style.Visibility.SpeedOverall {
return
}
if !hint.isOverallTracker && !p.style.Visibility.Speed {
return
}

speedPrecision := p.style.Options.SpeedPrecision
writeSpeed := func(speed string) {
if p.style.Options.SpeedPosition == PositionRight {
out.WriteString("; ")
}
out.WriteString(p.style.Colors.Speed.Sprint(speed))
out.WriteString(p.style.Options.SpeedSuffix)
if p.style.Options.SpeedPosition == PositionLeft {
out.WriteString("; ")
}
}

if hint.isOverallTracker {
speed := float64(0)

p.trackersActiveMutex.RLock()
for _, tracker := range p.trackersActive {
speed += float64(tracker.Value()) / time.Since(tracker.timeStart).Round(speedPrecision).Seconds()
}
p.trackersActiveMutex.RUnlock()

if speed > 0 {
writeSpeed(p.style.Options.SpeedOverallFormatter(int64(speed)))
}
} else {
timeTaken := time.Since(t.timeStart)
if timeTakenRounded := timeTaken.Round(speedPrecision); timeTakenRounded > speedPrecision {
writeSpeed(t.Units.Sprint(int64(float64(t.Value()) / timeTakenRounded.Seconds())))
}
}
}

func (p *Progress) renderTrackerStatsTime(outStats *strings.Builder, t *Tracker, hint renderHint) {
var td, tp time.Duration
if t.IsDone() {
Expand Down Expand Up @@ -375,42 +419,3 @@ func (p *Progress) renderTrackerStatsETA(out *strings.Builder, t *Tracker, hint
out.WriteString(p.style.Colors.Time.Sprint(eta))
}
}

func (p *Progress) renderTrackerSpeed(out *strings.Builder, t *Tracker, hint renderHint) {
if hint.isOverallTracker && !p.style.Visibility.SpeedOverall {
return
}
if !hint.isOverallTracker && !p.style.Visibility.Speed {
return
}

tpSpeed := p.style.Options.SpeedPrecision

write := func(speed float64, formatter func(int64) string) {
if formatter == nil {
formatter = FormatNumber
}
out.WriteString(p.style.Colors.Speed.Sprint(formatter(int64(speed))))
out.WriteString("/s; ")
}

if hint.isOverallTracker {
speed := float64(0)

p.trackersActiveMutex.RLock()
for _, tracker := range p.trackersActive {
speed += float64(tracker.Value()) / time.Since(tracker.timeStart).Round(tpSpeed).Seconds()
}
p.trackersActiveMutex.RUnlock()

if speed > 0 {
write(speed, p.style.Options.SpeedOverallFormatter)
}
return
}

since := time.Since(t.timeStart)
if eta := since.Round(tpSpeed); eta > tpSpeed {
write(float64(t.Value())/eta.Seconds(), t.Units.Formatter)
}
}

0 comments on commit fb89930

Please sign in to comment.