Atlas › Test

TestEventTimeSource_NewTimerWithChannelAndReset

Exact test identity: go.temporal.io/server/common/clock/TestEventTimeSource_NewTimerWithChannelAndReset

Package
go.temporal.io/server/common/clock
Suite / test hierarchy
TestEventTimeSource_NewTimerWithChannelAndReset
Test
TestEventTimeSource_NewTimerWithChannelAndReset
Introduced at
event_time_source.go ×1 Frontier kind: Joint frontier
Covered ranges
20
Covered lines
65
Covered files
1

Covered source

Expand a file to inspect source; the > gutter marks covered lines.

go.temporal.io/server/common/clock/event_time_source.go 65 covered LOC · 20 ranges

Open complete file

39
40 // NewEventTimeSource returns a EventTimeSource with the current time set to Unix zero: 1970-01-01 00:00:00 +0000 UTC.
41 > func NewEventTimeSource() *EventTimeSource { event_time_source.go
42 > return &EventTimeSource{
43 > now: time.Unix(0, 0),
44 > }
45 > }
46
47 // Some clients depend on the fact that the runtime's timers do _not_ run synchronously.
55
56 // Now return the current time.
57 > func (ts *EventTimeSource) Now() time.Time { event_time_source.go
58 > ts.mu.RLock()
59 > defer ts.mu.RUnlock()
60 >
61 > return ts.now
62 > }
63
64 func (ts *EventTimeSource) Since(t time.Time) time.Duration {
82 // NewTimer creates a Timer that will send the current time on a channel after at least
83 // duration d. It returns the channel and the Timer.
84 > func (ts *EventTimeSource) NewTimer(d time.Duration) (<-chan time.Time, Timer) { event_time_source.go
85 > c := make(chan time.Time, 1)
86 > // we can't call ts.Now() from the callback so just calculate what it should be
87 > target := ts.Now().Add(d)
88 > timer := &fakeTimer{
89 > timeSource: ts,
90 > deadline: target,
91 > callback: func() { c <- target },
92 c: c,
93 }
94 > ts.addTimer(timer) event_time_source.go
95 > return c, timer
96 }
97
98 > func (ts *EventTimeSource) addTimer(t *fakeTimer) { event_time_source.go
99 > ts.mu.Lock()
100 > defer ts.mu.Unlock()
101 > t.index = len(ts.timers)
102 > ts.timers = append(ts.timers, t)
103 > ts.fireTimers()
104 > }
105
106 // Update the fake current time. It returns the timeSource so that you can chain calls like this:
116
117 // Advance the timer by the specified duration.
118 > func (ts *EventTimeSource) Advance(d time.Duration) { event_time_source.go
119 > ts.mu.Lock()
120 > defer ts.mu.Unlock()
121 >
122 > ts.now = ts.now.Add(d)
123 > ts.fireTimers()
124 > }
125
126 // AdvanceNext advances to the next timer.
156
157 // fireTimers fires all timers that are ready.
158 > func (ts *EventTimeSource) fireTimers() { event_time_source.go
159 > n := 0
160 > for _, t := range ts.timers {
161 > if t.deadline.After(ts.now) { event_time_source.go
162 > ts.timers[n] = t event_time_source.go
163 > t.index = n
164 > n++
165 > } else { event_time_source.go
166 > if ts.async { event_time_source.go
167 go t.callback()
168 > } else { event_time_source.go
169 > t.callback() event_time_source.go
170 > }
171 > t.done = true event_time_source.go
172 }
173 }
174 > ts.timers = ts.timers[:n] event_time_source.go
175 }
176
177 // Reset the timer to fire after the specified duration. Returns true if the timer was active.
178 > func (t *fakeTimer) Reset(d time.Duration) bool { event_time_source.go
179 > t.timeSource.mu.Lock()
180 > defer t.timeSource.mu.Unlock()
181 >
182 > if d < 0 {
183 d = 0
184 }
185
186 > wasActive := !t.done event_time_source.go
187 > t.deadline = t.timeSource.now.Add(d)
188 > if t.done {
189 > t.done = false event_time_source.go
190 > t.index = len(t.timeSource.timers)
191 > t.timeSource.timers = append(t.timeSource.timers, t)
192 > // Only reset the callback if this timer was created via NewTimer
193 > if t.c != nil {
194 > t.callback = func() { t.c <- t.deadline } event_time_source.go
195 }
196 }
197 > t.timeSource.fireTimers() event_time_source.go
198 > return wasActive
199 }
200