mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-03-09 08:59:30 +00:00
Several packages are only used while running the e2e suite. These packages are less important to update, as the they can not influence the final executable that is part of the Ceph-CSI container-image. By moving these dependencies out of the main Ceph-CSI go.mod, it is easier to identify if a reported CVE affects Ceph-CSI, or only the testing (like most of the Kubernetes CVEs). Signed-off-by: Niels de Vos <ndevos@ibm.com>
98 lines
2.1 KiB
Go
98 lines
2.1 KiB
Go
package backoff
|
|
|
|
import (
|
|
"context"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
// Ticker holds a channel that delivers `ticks' of a clock at times reported by a BackOff.
|
|
//
|
|
// Ticks will continue to arrive when the previous operation is still running,
|
|
// so operations that take a while to fail could run in quick succession.
|
|
type Ticker struct {
|
|
C <-chan time.Time
|
|
c chan time.Time
|
|
b BackOff
|
|
ctx context.Context
|
|
timer Timer
|
|
stop chan struct{}
|
|
stopOnce sync.Once
|
|
}
|
|
|
|
// NewTicker returns a new Ticker containing a channel that will send
|
|
// the time at times specified by the BackOff argument. Ticker is
|
|
// guaranteed to tick at least once. The channel is closed when Stop
|
|
// method is called or BackOff stops. It is not safe to manipulate the
|
|
// provided backoff policy (notably calling NextBackOff or Reset)
|
|
// while the ticker is running.
|
|
func NewTicker(b BackOff) *Ticker {
|
|
return NewTickerWithTimer(b, &defaultTimer{})
|
|
}
|
|
|
|
// NewTickerWithTimer returns a new Ticker with a custom timer.
|
|
// A default timer that uses system timer is used when nil is passed.
|
|
func NewTickerWithTimer(b BackOff, timer Timer) *Ticker {
|
|
if timer == nil {
|
|
timer = &defaultTimer{}
|
|
}
|
|
c := make(chan time.Time)
|
|
t := &Ticker{
|
|
C: c,
|
|
c: c,
|
|
b: b,
|
|
ctx: getContext(b),
|
|
timer: timer,
|
|
stop: make(chan struct{}),
|
|
}
|
|
t.b.Reset()
|
|
go t.run()
|
|
return t
|
|
}
|
|
|
|
// Stop turns off a ticker. After Stop, no more ticks will be sent.
|
|
func (t *Ticker) Stop() {
|
|
t.stopOnce.Do(func() { close(t.stop) })
|
|
}
|
|
|
|
func (t *Ticker) run() {
|
|
c := t.c
|
|
defer close(c)
|
|
|
|
// Ticker is guaranteed to tick at least once.
|
|
afterC := t.send(time.Now())
|
|
|
|
for {
|
|
if afterC == nil {
|
|
return
|
|
}
|
|
|
|
select {
|
|
case tick := <-afterC:
|
|
afterC = t.send(tick)
|
|
case <-t.stop:
|
|
t.c = nil // Prevent future ticks from being sent to the channel.
|
|
return
|
|
case <-t.ctx.Done():
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
func (t *Ticker) send(tick time.Time) <-chan time.Time {
|
|
select {
|
|
case t.c <- tick:
|
|
case <-t.stop:
|
|
return nil
|
|
}
|
|
|
|
next := t.b.NextBackOff()
|
|
if next == Stop {
|
|
t.Stop()
|
|
return nil
|
|
}
|
|
|
|
t.timer.Start(next)
|
|
return t.timer.C()
|
|
}
|