// ServiceProgress outputs progress information for convergence of a service.
// nolint: gocyclo
542589
func ServiceProgress(ctx context.Context, client client.APIClient, serviceID string, progressWriter io.WriteCloser) error {
	defer progressWriter.Close()

	progressOut := streamformatter.NewJSONProgressOutput(progressWriter, false)

	sigint := make(chan os.Signal, 1)
	signal.Notify(sigint, os.Interrupt)
	defer signal.Stop(sigint)

	taskFilter := filters.NewArgs()
	taskFilter.Add("service", serviceID)
	taskFilter.Add("_up-to-date", "true")

	getUpToDateTasks := func() ([]swarm.Task, error) {
		return client.TaskList(ctx, types.TaskListOptions{Filters: taskFilter})
	}

	var (
		updater     progressUpdater
		converged   bool
		convergedAt time.Time
		monitor     = 5 * time.Second
		rollback    bool
	)

	for {
		service, _, err := client.ServiceInspectWithRaw(ctx, serviceID, types.ServiceInspectOptions{})
		if err != nil {
			return err
		}

		if service.Spec.UpdateConfig != nil && service.Spec.UpdateConfig.Monitor != 0 {
			monitor = service.Spec.UpdateConfig.Monitor
		}

		if updater == nil {
			updater, err = initializeUpdater(service, progressOut)
			if err != nil {
				return err
			}
		}

		if service.UpdateStatus != nil {
			switch service.UpdateStatus.State {
			case swarm.UpdateStateUpdating:
				rollback = false
			case swarm.UpdateStateCompleted:
				if !converged {
					return nil
				}
			case swarm.UpdateStatePaused:
				return fmt.Errorf("service update paused: %s", service.UpdateStatus.Message)
			case swarm.UpdateStateRollbackStarted:
				if !rollback && service.UpdateStatus.Message != "" {
					progressOut.WriteProgress(progress.Progress{
						ID:     "rollback",
						Action: service.UpdateStatus.Message,
					})
				}
				rollback = true
			case swarm.UpdateStateRollbackPaused:
				return fmt.Errorf("service rollback paused: %s", service.UpdateStatus.Message)
			case swarm.UpdateStateRollbackCompleted:
				if !converged {
					return fmt.Errorf("service rolled back: %s", service.UpdateStatus.Message)
				}
			}
		}
		if converged && time.Since(convergedAt) >= monitor {
			progressOut.WriteProgress(progress.Progress{
				ID:     "verify",
				Action: "Service converged",
			})

			return nil
		}

		tasks, err := getUpToDateTasks()
		if err != nil {
			return err
		}

		activeNodes, err := getActiveNodes(ctx, client)
		if err != nil {
			return err
		}

		converged, err = updater.update(service, tasks, activeNodes, rollback)
		if err != nil {
			return err
		}
		if converged {
			if convergedAt.IsZero() {
				convergedAt = time.Now()
			}
			wait := monitor - time.Since(convergedAt)
			if wait >= 0 {
				progressOut.WriteProgress(progress.Progress{
					// Ideally this would have no ID, but
					// the progress rendering code behaves
					// poorly on an "action" with no ID. It
					// returns the cursor to the beginning
					// of the line, so the first character
					// may be difficult to read. Then the
					// output is overwritten by the shell
					// prompt when the command finishes.
					ID:     "verify",
					Action: fmt.Sprintf("Waiting %d seconds to verify that tasks are stable...", wait/time.Second+1),
				})
			}
		} else {
			if !convergedAt.IsZero() {
				progressOut.WriteProgress(progress.Progress{
					ID:     "verify",
					Action: "Detected task failure",
				})
			}
			convergedAt = time.Time{}
		}

		select {
		case <-time.After(200 * time.Millisecond):
		case <-sigint:
			if !converged {
				progress.Message(progressOut, "", "Operation continuing in background.")
				progress.Messagef(progressOut, "", "Use `docker service ps %s` to check progress.", serviceID)
			}
			return nil
		}
	}
}
175964
func (ec *EthereumClient) SyncProgress(ctx *Context) (progress *SyncProgress, _ error) {
	rawProgress, err := ec.client.SyncProgress(ctx.context)
	if rawProgress == nil {
		return nil, err
	}
	return &SyncProgress{*rawProgress}, err
}
653875
func (clstr *Cluster) MigrationInProgress(timeout time.Duration) (res bool, err error) {
	if timeout <= 0 {
		timeout = _DEFAULT_TIMEOUT
	}

	done := make(chan bool, 1)

	go func() {
		// this function is guaranteed to return after _DEFAULT_TIMEOUT
		nodes := clstr.GetNodes()
		for _, node := range nodes {
			if node.IsActive() {
				if res, err = node.MigrationInProgress(); res || err != nil {
					done <- true
					return
				}
			}
		}

		res, err = false, nil
		done <- false
	}()

	dealine := time.After(timeout)
	for {
		select {
		case <-dealine:
			return false, NewAerospikeError(TIMEOUT)
		case <-done:
			return res, err
		}
	}
}
650217
func NewProgressEmitter(cfg config.Wrapper) *ProgressEmitter {
	t := &ProgressEmitter{
		stop:               make(chan struct{}),
		registry:           make(map[string]map[string]*sharedPullerState),
		timer:              time.NewTimer(time.Millisecond),
		sentDownloadStates: make(map[protocol.DeviceID]*sentDownloadState),
		connections:        make(map[protocol.DeviceID]protocol.Connection),
		foldersByConns:     make(map[protocol.DeviceID][]string),
		mut:                sync.NewMutex(),
	}

	t.CommitConfiguration(config.Configuration{}, cfg.RawCopy())
	cfg.Subscribe(t)

	return t
}
1007842
func (s *ProgressDetail) SetCurrentProgress(v string) *ProgressDetail {
	s.CurrentProgress = &v
	return s
}
317397
func NewProgressFileReader(file string) (*ProgressReader, <-chan Progress, error) {
	f, ferr := os.Open(file)
	if ferr != nil {
		return nil, nil, ferr
	}
	// Get the filesize by seeking to the end of the file, and back to offset 0
	fsize, err := f.Seek(0, os.SEEK_END)
	if err != nil {
		return nil, nil, err
	}
	if _, err := f.Seek(0, os.SEEK_SET); err != nil {
		return nil, nil, err
	}
	io, ch := NewProgressReader(f, fsize)
	return io, ch, nil
}
1168300
func (c *Core) RekeyProgress(recovery, verification bool) (bool, int, logical.HTTPCodedError) {
	c.stateLock.RLock()
	defer c.stateLock.RUnlock()
	if c.Sealed() {
		return false, 0, logical.CodedError(http.StatusServiceUnavailable, consts.ErrSealed.Error())
	}
	if c.standby {
		return false, 0, logical.CodedError(http.StatusBadRequest, consts.ErrStandby.Error())
	}

	c.rekeyLock.RLock()
	defer c.rekeyLock.RUnlock()

	var conf *SealConfig
	if recovery {
		conf = c.recoveryRekeyConfig
	} else {
		conf = c.barrierRekeyConfig
	}

	if conf == nil {
		return false, 0, logical.CodedError(http.StatusBadRequest, "rekey operation not in progress")
	}

	if verification {
		return len(conf.VerificationKey) > 0, len(conf.VerificationProgress), nil
	}
	return true, len(conf.RekeyProgress), nil
}
1073513
func (s *MigrationTaskSummary) SetProgressUpdateStream(v string) *MigrationTaskSummary {
	s.ProgressUpdateStream = &v
	return s
}
744016
func (s *DiskSnapshot) SetProgress(v string) *DiskSnapshot {
	s.Progress = &v
	return s
}
930474
func checkoutProgressCallback(path *C.char, completed_steps, total_steps C.size_t, data unsafe.Pointer) int {
	opts := pointerHandles.Get(data).(*CheckoutOpts)
	if opts.ProgressCallback == nil {
		return 0
	}
	return int(opts.ProgressCallback(C.GoString(path), uint(completed_steps), uint(total_steps)))
}
751651
func (c *rawConnection) DownloadProgress(folder string, updates []FileDownloadProgressUpdate) {
	c.send(&DownloadProgress{
		Folder:  folder,
		Updates: updates,
	}, nil)
}
454939
func (mp *MultiProgressBar) AddProgressBar(p *ProgressBar) {
	mp.ProgressBars = append(mp.ProgressBars, p)

	if len(mp.ProgressBars) > 1 {
		fmt.Println()
	}
	mp.Print()
}
1017984
func (out *lastProgressOutput) WriteProgress(prog progress.Progress) error {
	if !prog.LastUpdate {
		return nil
	}

	return out.output.WriteProgress(prog)
}
521851
func (c *Client) UploadVideoWithProgress(filePath string, cb func(*ProgressInfo)) (VideoInfo, error) {
	return uploadVideo(c.creds, filePath, cb)
}
1123049
func (s *Tape) SetProgress(v float64) *Tape {
	s.Progress = &v
	return s
}
1264538
func (c *ProgressBar) SetProgress(p int) {
	if (p <= c.total || c.allowOverflow) || (p >= 0 || c.allowUnderflow) {
		c.progress = p
	}
}
190991
func (s *MigrationTask) SetProgressUpdateStream(v string) *MigrationTask {
	s.ProgressUpdateStream = &v
	return s
}