MCPcopy
hub / github.com/kopia/kopia / NewTimer

Function NewTimer

internal/sleepable/sleepable_timer.go:27–78  ·  view source on GitHub ↗

NewTimer creates a new timer that will trigger at the given time.

(nowFunc func() time.Time, until time.Time)

Source from the content-addressed store, hash-verified

25
26// NewTimer creates a new timer that will trigger at the given time.
27func NewTimer(nowFunc func() time.Time, until time.Time) *Timer {
28 ch := make(chan struct{})
29
30 t := &Timer{
31 C: ch,
32 stopChan: make(chan struct{}),
33 }
34
35 var currentTimer *time.Timer
36
37 // capture maxSleepTime at the start of the goroutine to avoid race conditions.
38 maxSleepTime := MaxSleepTime
39
40 // start a goroutine that will sleep until the timer is triggered or the timer is stopped.
41 go func() {
42 defer func() {
43 if currentTimer != nil {
44 currentTimer.Stop()
45 }
46 }()
47
48 for {
49 now := nowFunc()
50
51 // when the current time is after the target time, the timer immediately triggers by closing the channel.
52 if now.After(until) {
53 close(ch)
54 return
55 }
56
57 nextSleepTime := min(until.Sub(now), maxSleepTime)
58
59 if currentTimer != nil {
60 currentTimer.Stop()
61 }
62
63 currentTimer = time.NewTimer(nextSleepTime)
64
65 select {
66 case <-t.stopChan:
67 // stop channel was closed, exit without closing the "C" channel
68 return
69
70 case <-currentTimer.C:
71 // timer did trigger, re-execute the loop to see if we reached the target time
72 continue
73 }
74 }
75 }()
76
77 return t
78}

Callers 6

runMethod · 0.92
TestNewTimerFunction · 0.85
TestTimerStopFunction · 0.85
TestTimerConcurrentStopFunction · 0.85
TestTimerEdgeCasesFunction · 0.85
TestTimerChannelBehaviorFunction · 0.85

Calls 3

StopMethod · 0.95
AfterMethod · 0.80
SubMethod · 0.80

Tested by 5

TestNewTimerFunction · 0.68
TestTimerStopFunction · 0.68
TestTimerConcurrentStopFunction · 0.68
TestTimerEdgeCasesFunction · 0.68
TestTimerChannelBehaviorFunction · 0.68