Skip to content

Commit 9d82324

Browse files
authored
Merge pull request #3 from vimeo/fake_clock_track_early_risers
fake clock: track early risers
2 parents 408b307 + fd3420e commit 9d82324

File tree

2 files changed

+14
-6
lines changed

2 files changed

+14
-6
lines changed

campaign_test.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -469,10 +469,9 @@ func TestAcquireAndReplaceWithFakeClockAndSkew(t *testing.T) {
469469
// now, advance all the way to the end of the term according to the
470470
// second candidate (the second candidate should still be sleeping
471471
// anyway)
472-
// However, the lock-holder was supposed to wake up to refresh its
473-
// lease.
474-
if awoken := fc.Advance(time.Microsecond); awoken != 1 {
475-
t.Errorf("too many sleepers awoken %d; wanted 1", awoken)
472+
// no one should awaken since the original lock holder had its context cancelled.
473+
if awoken := fc.Advance(time.Microsecond); awoken != 0 {
474+
t.Errorf("too many sleepers awoken %d; wanted 0", awoken)
476475
}
477476
// In this test, the max clock-skew exactly matches the skew for our
478477
// second candidate, so we should still need another second in

clocks/fake_clock.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ func (f *FakeClock) Until(t time.Time) time.Duration {
118118
return t.Sub(f.Now())
119119
}
120120

121-
func (f *FakeClock) setAbsoluteWaiter(until time.Time) <-chan struct{} {
121+
func (f *FakeClock) setAbsoluteWaiter(until time.Time) chan struct{} {
122122
ch := make(chan struct{})
123123
f.mu.Lock()
124124
defer f.mu.Unlock()
@@ -132,11 +132,19 @@ func (f *FakeClock) setAbsoluteWaiter(until time.Time) <-chan struct{} {
132132
return ch
133133
}
134134

135+
func (f *FakeClock) removeWaiter(ch chan struct{}) {
136+
f.mu.Lock()
137+
defer f.mu.Unlock()
138+
delete(f.sleepers, ch)
139+
f.cond.Broadcast()
140+
}
141+
135142
// SleepUntil blocks until either ctx expires or until arrives.
136143
// Return value is false if context-cancellation/expiry prompted an
137144
// early return
138145
func (f *FakeClock) SleepUntil(ctx context.Context, until time.Time) bool {
139146
ch := f.setAbsoluteWaiter(until)
147+
defer f.removeWaiter(ch)
140148
select {
141149
case <-ch:
142150
return true
@@ -145,7 +153,7 @@ func (f *FakeClock) SleepUntil(ctx context.Context, until time.Time) bool {
145153
}
146154
}
147155

148-
func (f *FakeClock) setRelativeWaiter(dur time.Duration) <-chan struct{} {
156+
func (f *FakeClock) setRelativeWaiter(dur time.Duration) chan struct{} {
149157
ch := make(chan struct{})
150158
f.mu.Lock()
151159
defer f.mu.Unlock()
@@ -160,6 +168,7 @@ func (f *FakeClock) SleepFor(ctx context.Context, dur time.Duration) bool {
160168
return true
161169
}
162170
ch := f.setRelativeWaiter(dur)
171+
defer f.removeWaiter(ch)
163172
select {
164173
case <-ch:
165174
return true

0 commit comments

Comments
 (0)