progress: Update printer to support intervals.

The previous updates for start/stop intervals only updated the tty
display. Now, corresponding changes have been made to the plain progress
printer too.

Signed-off-by: Erik Sipsma <erik@sipsma.dev>
This commit is contained in:
Erik Sipsma
2022-03-04 18:12:38 -08:00
parent 0a7d8907ae
commit 87bfcc0e65
2 changed files with 53 additions and 28 deletions

View File

@@ -155,7 +155,7 @@ type vertex struct {
// Interval start time in unix nano -> interval. Using a map ensures
// that updates for the same interval overwrite their previous updates.
intervals map[int64]interval
mostRecentStart *time.Time
mergedIntervals []interval
// whether the vertex should be hidden due to being in a progress group
// that doesn't have any non-weak members that have started
@@ -170,17 +170,23 @@ func (v *vertex) update(c int) {
v.count += c
}
func (v *vertex) mostRecentInterval() *interval {
if v.isStarted() {
ival := v.mergedIntervals[len(v.mergedIntervals)-1]
return &ival
}
return nil
}
func (v *vertex) isStarted() bool {
return len(v.intervals) > 0
return len(v.mergedIntervals) > 0
}
func (v *vertex) isCompleted() bool {
for _, ival := range v.intervals {
if ival.stop == nil {
return false
}
if ival := v.mostRecentInterval(); ival != nil {
return ival.stop != nil
}
return true
return false
}
type vertexGroup struct {
@@ -207,9 +213,6 @@ func (vg *vertexGroup) refresh() (changed, newlyStarted, newlyRevealed bool) {
newlyStarted = true
}
vg.intervals[subVtx.Started.UnixNano()] = newInterval
if vg.mostRecentStart == nil || subVtx.Started.After(*vg.mostRecentStart) {
vg.mostRecentStart = subVtx.Started
}
if !subVtx.ProgressGroup.Weak {
vg.hidden = false
@@ -240,6 +243,12 @@ func (vg *vertexGroup) refresh() (changed, newlyStarted, newlyRevealed bool) {
newlyRevealed = true
}
var ivals []interval
for _, ival := range vg.intervals {
ivals = append(ivals, ival)
}
vg.mergedIntervals = mergeIntervals(ivals)
return changed, newlyStarted, newlyRevealed
}
@@ -463,9 +472,11 @@ func (t *trace) update(s *client.SolveStatus, termWidth int) {
start: v.Started,
stop: v.Completed,
}
if t.byDigest[v.Digest].mostRecentStart == nil || v.Started.After(*t.byDigest[v.Digest].mostRecentStart) {
t.byDigest[v.Digest].mostRecentStart = v.Started
var ivals []interval
for _, ival := range t.byDigest[v.Digest].intervals {
ivals = append(ivals, ival)
}
t.byDigest[v.Digest].mergedIntervals = mergeIntervals(ivals)
}
t.byDigest[v.Digest].jobCached = false
}
@@ -474,7 +485,7 @@ func (t *trace) update(s *client.SolveStatus, termWidth int) {
changed, newlyStarted, newlyRevealed := group.refresh()
if newlyStarted {
if t.localTimeDiff == 0 {
t.localTimeDiff = time.Since(*group.mostRecentStart)
t.localTimeDiff = time.Since(*group.mergedIntervals[0].start)
}
}
if group.hidden {
@@ -534,8 +545,8 @@ func (t *trace) update(s *client.SolveStatus, termWidth int) {
v.logs[len(v.logs)-1] = append(v.logs[len(v.logs)-1], dt...)
} else {
ts := time.Duration(0)
if v.isStarted() {
ts = l.Timestamp.Sub(*v.mostRecentStart)
if ival := v.mostRecentInterval(); ival != nil {
ts = l.Timestamp.Sub(*ival.start)
}
prec := 1
sec := ts.Seconds()
@@ -648,15 +659,14 @@ func (t *trace) displayInfo() (d displayInfo) {
}
for _, w := range v.warnings {
msg := "WARN: " + string(w.Short)
mostRecentStart := v.mostRecentStart
var mostRecentStop *time.Time
if mostRecentStart != nil {
mostRecentStop = v.intervals[mostRecentStart.UnixNano()].stop
var mostRecentInterval interval
if ival := v.mostRecentInterval(); ival != nil {
mostRecentInterval = *ival
}
j := &job{
intervals: []interval{{
start: addTime(mostRecentStart, t.localTimeDiff),
stop: addTime(mostRecentStop, t.localTimeDiff),
start: addTime(mostRecentInterval.start, t.localTimeDiff),
stop: addTime(mostRecentInterval.stop, t.localTimeDiff),
}},
name: msg,
isCanceled: true,

View File

@@ -166,7 +166,7 @@ func (p *textMux) printVtx(t *trace, dgst digest.Digest) {
}
p.current = dgst
if v.Completed != nil && !isOpenStatus {
if v.isCompleted() && !isOpenStatus {
p.current = ""
v.count = 0
@@ -183,8 +183,17 @@ func (p *textMux) printVtx(t *trace, dgst digest.Digest) {
fmt.Fprintf(p.w, "#%d CACHED\n", v.index)
} else {
tm := ""
if v.Started != nil {
tm = fmt.Sprintf(" %.1fs", v.Completed.Sub(*v.Started).Seconds())
var ivals []interval
for _, ival := range v.intervals {
ivals = append(ivals, ival)
}
ivals = mergeIntervals(ivals)
if len(ivals) > 0 {
var dt float64
for _, ival := range ivals {
dt += ival.duration().Seconds()
}
tm = fmt.Sprintf(" %.1fs", dt)
}
fmt.Fprintf(p.w, "#%d DONE%s\n", v.index, tm)
}
@@ -199,7 +208,9 @@ func sortCompleted(t *trace, m map[digest.Digest]struct{}) []digest.Digest {
out = append(out, k)
}
sort.Slice(out, func(i, j int) bool {
return t.byDigest[out[i]].Completed.Before(*t.byDigest[out[j]].Completed)
vtxi := t.byDigest[out[i]]
vtxj := t.byDigest[out[j]]
return vtxi.mostRecentInterval().stop.Before(*vtxj.mostRecentInterval().stop)
})
return out
}
@@ -213,7 +224,11 @@ func (p *textMux) print(t *trace) {
if !ok {
continue
}
if v.Vertex.Completed != nil {
if v.ProgressGroup != nil || v.hidden {
// skip vtxs in a group (they are merged into a single vtx) and hidden ones
continue
}
if v.isCompleted() {
completed[dgst] = struct{}{}
} else {
rest[dgst] = struct{}{}
@@ -235,13 +250,13 @@ func (p *textMux) print(t *trace) {
if len(rest) == 0 {
if current != "" {
if v := t.byDigest[current]; v.Started != nil && v.Completed == nil {
if v := t.byDigest[current]; v.isStarted() && !v.isCompleted() {
return
}
}
// make any open vertex active
for dgst, v := range t.byDigest {
if v.Started != nil && v.Completed == nil {
if v.isStarted() && !v.isCompleted() {
p.printVtx(t, dgst)
return
}