10 // PercentageTask is a task that is performed against a known number of
12 type PercentageTask struct {
13 // members managed via sync/atomic must be aligned at the top of this
14 // structure (see: https://github.com/git-lfs/git-lfs/pull/2880).
16 // n is the number of elements whose work has been completed. It is
17 // managed sync/atomic.
19 // total is the total number of elements to execute work upon.
21 // msg is the task message.
23 // ch is a channel which is written to when the task state changes and
24 // is closed when the task is completed.
28 func NewPercentageTask(msg string, total uint64) *PercentageTask {
32 ch: make(chan *Update, 1),
39 // Count indicates that work has been completed against "n" number of elements,
40 // marking the task as complete if the total "n" given to all invocations of
41 // this method is equal to total.
43 // Count returns the new total number of (atomically managed) elements that have
45 func (c *PercentageTask) Count(n uint64) (new uint64) {
46 if new = atomic.AddUint64(&c.n, n); new > c.total {
47 panic("tasklog: counted too many items")
50 var percentage float64
54 percentage = 100 * float64(new) / float64(c.total)
58 S: fmt.Sprintf("%s: %3.f%% (%d/%d)",
59 c.msg, math.Floor(percentage), new, c.total),
70 // Entry logs a line-delimited task entry.
71 func (t *PercentageTask) Entry(update string) {
73 S: fmt.Sprintf("%s\n", update),
79 // Updates implements Task.Updates and returns a channel which is written to
80 // when the state of this task changes, and closed when the task is completed.
81 // has been completed.
82 func (c *PercentageTask) Updates() <-chan *Update {
86 // Throttled implements Task.Throttled and returns true, indicating that this
88 func (c *PercentageTask) Throttled() bool { return true }