Merge pull request #43359 from smarterclayton/reuse_timer

Automatic merge from submit-queue

JitterUntil should reuse Timer instead of allocating
This commit is contained in:
Kubernetes Submit Queue 2017-03-25 19:57:38 -07:00 committed by GitHub
commit f4d863a655

View File

@ -73,8 +73,10 @@ func NonSlidingUntil(f func(), period time.Duration, stopCh <-chan struct{}) {
// Close stopCh to stop. f may not be invoked if stop channel is already // Close stopCh to stop. f may not be invoked if stop channel is already
// closed. Pass NeverStop to if you don't want it stop. // closed. Pass NeverStop to if you don't want it stop.
func JitterUntil(f func(), period time.Duration, jitterFactor float64, sliding bool, stopCh <-chan struct{}) { func JitterUntil(f func(), period time.Duration, jitterFactor float64, sliding bool, stopCh <-chan struct{}) {
for { var t *time.Timer
var sawTimeout bool
for {
select { select {
case <-stopCh: case <-stopCh:
return return
@ -86,9 +88,8 @@ func JitterUntil(f func(), period time.Duration, jitterFactor float64, sliding b
jitteredPeriod = Jitter(period, jitterFactor) jitteredPeriod = Jitter(period, jitterFactor)
} }
var t *time.Timer
if !sliding { if !sliding {
t = time.NewTimer(jitteredPeriod) t = resetOrReuseTimer(t, jitteredPeriod, sawTimeout)
} }
func() { func() {
@ -97,7 +98,7 @@ func JitterUntil(f func(), period time.Duration, jitterFactor float64, sliding b
}() }()
if sliding { if sliding {
t = time.NewTimer(jitteredPeriod) t = resetOrReuseTimer(t, jitteredPeriod, sawTimeout)
} }
// NOTE: b/c there is no priority selection in golang // NOTE: b/c there is no priority selection in golang
@ -109,6 +110,7 @@ func JitterUntil(f func(), period time.Duration, jitterFactor float64, sliding b
case <-stopCh: case <-stopCh:
return return
case <-t.C: case <-t.C:
sawTimeout = true
} }
} }
} }
@ -330,3 +332,16 @@ func poller(interval, timeout time.Duration) WaitFunc {
return ch return ch
}) })
} }
// resetOrReuseTimer avoids allocating a new timer if one is already in use.
// Not safe for multiple threads.
func resetOrReuseTimer(t *time.Timer, d time.Duration, sawTimeout bool) *time.Timer {
if t == nil {
return time.NewTimer(d)
}
if !t.Stop() && !sawTimeout {
<-t.C
}
t.Reset(d)
return t
}