Browse Source

progress: minor correctness fixes (#10871)

* When waiting for dependencies, `select` on the context as well
  as the ticker
* Write multiple progress events "transactionally" (i.e. hold the
  lock for the duration to avoid other events being interleaved)
* Do not change "finished" steps back to "in progress" to prevent
  flickering

Signed-off-by: Milas Bowman <[email protected]>
Milas Bowman 2 years ago
parent
commit
80856eacaf
2 changed files with 18 additions and 3 deletions
  1. 5 1
      pkg/compose/convergence.go
  2. 13 2
      pkg/progress/tty.go

+ 5 - 1
pkg/compose/convergence.go

@@ -324,7 +324,11 @@ func (s *composeService) waitDependencies(ctx context.Context, project *types.Pr
 			ticker := time.NewTicker(500 * time.Millisecond)
 			defer ticker.Stop()
 			for {
-				<-ticker.C
+				select {
+				case <-ticker.C:
+				case <-ctx.Done():
+					return nil
+				}
 				switch config.Condition {
 				case ServiceConditionRunningOrHealthy:
 					healthy, err := s.isServiceHealthy(ctx, waitingFor, true)

+ 13 - 2
pkg/progress/tty.go

@@ -73,6 +73,10 @@ func (w *ttyWriter) Stop() {
 func (w *ttyWriter) Event(e Event) {
 	w.mtx.Lock()
 	defer w.mtx.Unlock()
+	w.event(e)
+}
+
+func (w *ttyWriter) event(e Event) {
 	if !utils.StringContains(w.eventIDs, e.ID) {
 		w.eventIDs = append(w.eventIDs, e.ID)
 	}
@@ -80,9 +84,14 @@ func (w *ttyWriter) Event(e Event) {
 		last := w.events[e.ID]
 		switch e.Status {
 		case Done, Error, Warning:
-			if last.Status != e.Status {
+			if last.endTime.IsZero() {
 				last.stop()
 			}
+		case Working:
+			if !last.endTime.IsZero() {
+				// already done, don't overwrite
+				return
+			}
 		}
 		last.Status = e.Status
 		last.Text = e.Text
@@ -106,8 +115,10 @@ func (w *ttyWriter) Event(e Event) {
 }
 
 func (w *ttyWriter) Events(events []Event) {
+	w.mtx.Lock()
+	defer w.mtx.Unlock()
 	for _, e := range events {
-		w.Event(e)
+		w.event(e)
 	}
 }