Writes and verify image
This commit is contained in:
121
clitools/pkg/controller/osimage/progress.go
Normal file
121
clitools/pkg/controller/osimage/progress.go
Normal file
@@ -0,0 +1,121 @@
|
||||
package osimage
|
||||
|
||||
import (
|
||||
"k8s.io/klog/v2"
|
||||
"time"
|
||||
)
|
||||
|
||||
type progressState struct {
|
||||
lastTime time.Time
|
||||
lastPercent int64
|
||||
lastBucket int64
|
||||
}
|
||||
|
||||
type ProgressLogger struct {
|
||||
minInterval time.Duration
|
||||
bucketSize int64
|
||||
states map[string]*progressState
|
||||
}
|
||||
|
||||
func NewProgressLogger(minSeconds int, bucketSize int64) *ProgressLogger {
|
||||
if minSeconds < 0 {
|
||||
minSeconds = 0
|
||||
}
|
||||
if bucketSize <= 0 {
|
||||
bucketSize = 10
|
||||
}
|
||||
|
||||
return &ProgressLogger{
|
||||
minInterval: time.Duration(minSeconds) * time.Second,
|
||||
bucketSize: bucketSize,
|
||||
states: make(map[string]*progressState),
|
||||
}
|
||||
}
|
||||
|
||||
func (l *ProgressLogger) state(stage string) *progressState {
|
||||
s, ok := l.states[stage]
|
||||
if ok {
|
||||
return s
|
||||
}
|
||||
s = &progressState{
|
||||
lastPercent: -1,
|
||||
lastBucket: -1,
|
||||
}
|
||||
l.states[stage] = s
|
||||
return s
|
||||
}
|
||||
|
||||
func (l *ProgressLogger) Log(p Progress) {
|
||||
if p.BytesTotal <= 0 {
|
||||
return
|
||||
}
|
||||
|
||||
percent := PercentOf(p.BytesComplete, p.BytesTotal)
|
||||
|
||||
now := time.Now()
|
||||
bucket := percent / l.bucketSize
|
||||
s := l.state(p.Stage)
|
||||
|
||||
// Always log first visible progress
|
||||
if s.lastPercent == -1 {
|
||||
s.lastPercent = percent
|
||||
s.lastBucket = bucket
|
||||
s.lastTime = now
|
||||
klog.V(4).InfoS(p.Stage, "progress", percent)
|
||||
return
|
||||
}
|
||||
|
||||
// Always log completion once
|
||||
if percent == 100 && s.lastPercent < 100 {
|
||||
s.lastPercent = 100
|
||||
s.lastBucket = 100 / l.bucketSize
|
||||
s.lastTime = now
|
||||
klog.V(4).InfoS(p.Stage, "progress", 100)
|
||||
return
|
||||
}
|
||||
|
||||
// Log if we crossed a new milestone bucket
|
||||
if bucket > s.lastBucket {
|
||||
s.lastPercent = percent
|
||||
s.lastBucket = bucket
|
||||
s.lastTime = now
|
||||
klog.V(4).InfoS(p.Stage, "progress", percent)
|
||||
return
|
||||
}
|
||||
|
||||
// Otherwise allow a timed refresh if progress moved
|
||||
if now.Sub(s.lastTime) >= l.minInterval && percent > s.lastPercent {
|
||||
s.lastPercent = percent
|
||||
s.lastTime = now
|
||||
klog.V(4).InfoS(p.Stage, "progress", percent)
|
||||
}
|
||||
}
|
||||
|
||||
type TimeBasedUpdater struct {
|
||||
interval time.Duration
|
||||
lastRun time.Time
|
||||
}
|
||||
|
||||
func NewTimeBasedUpdater(seconds int) *TimeBasedUpdater {
|
||||
if seconds <= 0 {
|
||||
seconds = 15
|
||||
}
|
||||
return &TimeBasedUpdater{
|
||||
interval: time.Duration(seconds) * time.Second,
|
||||
}
|
||||
}
|
||||
|
||||
func (u *TimeBasedUpdater) Run(fn func() error) error {
|
||||
now := time.Now()
|
||||
|
||||
if !u.lastRun.IsZero() && now.Sub(u.lastRun) < u.interval {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := fn(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
u.lastRun = now
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user