2020-11-04 13:11:29 +00:00
|
|
|
package progress
|
|
|
|
|
|
|
|
import (
|
|
|
|
"sync"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
// A Func is a callback for a Counter.
|
|
|
|
//
|
|
|
|
// The final argument is true if Counter.Done has been called,
|
|
|
|
// which means that the current call will be the last.
|
2020-12-05 22:57:06 +00:00
|
|
|
type Func func(value uint64, total uint64, runtime time.Duration, final bool)
|
2020-11-04 13:11:29 +00:00
|
|
|
|
|
|
|
// A Counter tracks a running count and controls a goroutine that passes its
|
|
|
|
// value periodically to a Func.
|
|
|
|
//
|
|
|
|
// The Func is also called when SIGUSR1 (or SIGINFO, on BSD) is received.
|
|
|
|
type Counter struct {
|
2022-12-29 11:29:46 +00:00
|
|
|
Updater
|
2020-12-22 20:03:27 +00:00
|
|
|
|
|
|
|
valueMutex sync.Mutex
|
|
|
|
value uint64
|
2020-12-05 22:57:06 +00:00
|
|
|
max uint64
|
2020-11-04 13:11:29 +00:00
|
|
|
}
|
|
|
|
|
2022-12-29 11:29:46 +00:00
|
|
|
// NewCounter starts a new Counter.
|
|
|
|
func NewCounter(interval time.Duration, total uint64, report Func) *Counter {
|
2020-11-04 13:11:29 +00:00
|
|
|
c := &Counter{
|
2022-12-29 11:29:46 +00:00
|
|
|
max: total,
|
2020-11-04 13:11:29 +00:00
|
|
|
}
|
2022-12-29 11:29:46 +00:00
|
|
|
c.Updater = *NewUpdater(interval, func(runtime time.Duration, final bool) {
|
|
|
|
v, max := c.Get()
|
|
|
|
report(v, max, runtime, final)
|
|
|
|
})
|
2020-11-04 13:11:29 +00:00
|
|
|
return c
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add v to the Counter. This method is concurrency-safe.
|
|
|
|
func (c *Counter) Add(v uint64) {
|
|
|
|
if c == nil {
|
|
|
|
return
|
|
|
|
}
|
2020-12-22 20:03:27 +00:00
|
|
|
|
|
|
|
c.valueMutex.Lock()
|
|
|
|
c.value += v
|
|
|
|
c.valueMutex.Unlock()
|
2020-11-04 13:11:29 +00:00
|
|
|
}
|
|
|
|
|
2020-12-05 22:57:06 +00:00
|
|
|
// SetMax sets the maximum expected counter value. This method is concurrency-safe.
|
|
|
|
func (c *Counter) SetMax(max uint64) {
|
|
|
|
if c == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
c.valueMutex.Lock()
|
|
|
|
c.max = max
|
|
|
|
c.valueMutex.Unlock()
|
|
|
|
}
|
|
|
|
|
2022-10-25 05:41:44 +00:00
|
|
|
// Get returns the current value and the maximum of c.
|
|
|
|
// This method is concurrency-safe.
|
|
|
|
func (c *Counter) Get() (v, max uint64) {
|
2020-12-22 20:03:27 +00:00
|
|
|
c.valueMutex.Lock()
|
2022-10-25 05:41:44 +00:00
|
|
|
v, max = c.value, c.max
|
2020-12-22 20:03:27 +00:00
|
|
|
c.valueMutex.Unlock()
|
|
|
|
|
2022-10-25 05:41:44 +00:00
|
|
|
return v, max
|
2020-12-05 22:57:06 +00:00
|
|
|
}
|
|
|
|
|
2022-12-29 11:29:46 +00:00
|
|
|
func (c *Counter) Done() {
|
|
|
|
if c != nil {
|
|
|
|
c.Updater.Done()
|
2020-11-04 13:11:29 +00:00
|
|
|
}
|
|
|
|
}
|