Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(416)

Side by Side Diff: common/clock/testclock/testtimer.go

Issue 1679023005: Add Context cancellation to clock. (Closed) Base URL: https://github.com/luci/luci-go@master
Patch Set: More test coverage, cleanup, consolidation. Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package testclock 5 package testclock
6 6
7 import ( 7 import (
8 "time" 8 "time"
9 9
10 "github.com/luci/luci-go/common/clock" 10 "github.com/luci/luci-go/common/clock"
11 "golang.org/x/net/context"
11 ) 12 )
12 13
13 // timer is an implementation of clock.TestTimer that uses a channel 14 // timer is an implementation of clock.TestTimer that uses a channel
14 // to signal the timer to fire. 15 // to signal the timer to fire.
15 // 16 //
16 // The channel is buffered so it can be used without requiring a separate 17 // The channel is buffered so it can be used without requiring a separate
17 // signalling goroutine. 18 // signalling goroutine.
18 type timer struct { 19 type timer struct {
19 » clock *testClock 20 » ctx context.Context
20 » signalC chan time.Time 21 » clock *testClock
22
23 » // tags is the set of tags in the Context when this timer was created.
24 » tags []string
25
26 » // afterC will have the TimerResult of the timer's expiration written to it
27 » // when this timer triggers or is canceled.
28 » afterC chan clock.TimerResult
21 29
22 // Cancels callback from clock.invokeAt. Being not nil implies that the timer 30 // Cancels callback from clock.invokeAt. Being not nil implies that the timer
23 // is active. 31 // is active.
24 » cancelFunc cancelFunc 32 » cancelFunc context.CancelFunc
25 } 33 }
26 34
27 var _ clock.Timer = (*timer)(nil) 35 var _ clock.Timer = (*timer)(nil)
28 36
29 // NewTimer returns a new, instantiated timer. 37 // NewTimer returns a new, instantiated timer.
30 func newTimer(clock *testClock) clock.Timer { 38 func newTimer(ctx context.Context, clk *testClock) *timer {
31 return &timer{ 39 return &timer{
32 » » clock: clock, 40 » » ctx: ctx,
41 » » clock: clk,
42 » » tags: clock.Tags(ctx),
43 » » afterC: make(chan clock.TimerResult, 1),
33 } 44 }
34 } 45 }
35 46
36 func (t *timer) GetC() (c <-chan time.Time) { 47 func (t *timer) GetC() <-chan clock.TimerResult {
37 » if t.cancelFunc != nil { 48 » return t.afterC
38 » » c = t.signalC
39 » }
40 » return
41 } 49 }
42 50
43 func (t *timer) Reset(d time.Duration) (active bool) { 51 func (t *timer) Reset(d time.Duration) (active bool) {
44 now := t.clock.Now() 52 now := t.clock.Now()
45 triggerTime := now.Add(d) 53 triggerTime := now.Add(d)
46 54
47 // Signal our timerSet callback. 55 // Signal our timerSet callback.
56 afterC := make(chan clock.TimerResult, 1)
48 t.clock.signalTimerSet(d, t) 57 t.clock.signalTimerSet(d, t)
49 58
50 // Stop our current polling goroutine, if it's running. 59 // Stop our current polling goroutine, if it's running.
51 active = t.Stop() 60 active = t.Stop()
52 61
53 // Set timer properties. 62 // Set timer properties.
54 » t.signalC = make(chan time.Time, 1) 63 » var ctx context.Context
55 » t.cancelFunc = t.clock.invokeAt(triggerTime, t.signal) 64 » ctx, t.cancelFunc = context.WithCancel(t.ctx)
65 » t.clock.invokeAt(ctx, triggerTime, func(now time.Time, err error) {
66 » » t.cancelFunc = nil
iannucci 2016/02/10 22:30:28 Stop (https://golang.org/pkg/time/#Timer.Stop) sho
dnj (Google) 2016/02/11 01:26:54 Done.
67 » » afterC <- clock.TimerResult{Time: now, Err: err}
68 » })
69
70 » t.afterC = afterC
56 return 71 return
57 } 72 }
58 73
59 func (t *timer) Stop() bool { 74 func (t *timer) Stop() bool {
60 // If the timer is not running, we're done. 75 // If the timer is not running, we're done.
61 if t.cancelFunc == nil { 76 if t.cancelFunc == nil {
62 return false 77 return false
63 } 78 }
64 79
65 // Clear our state. 80 // Clear our state.
66 t.cancelFunc() 81 t.cancelFunc()
67 t.cancelFunc = nil 82 t.cancelFunc = nil
68 return true 83 return true
69 } 84 }
70 85
71 // Sends a single time signal. 86 // GetTags returns the tags associated with the specified timer. If the timer
72 func (t *timer) signal(now time.Time) { 87 // has no tags, an empty slice (nil) will be returned.
73 » if t.signalC != nil { 88 func GetTags(t clock.Timer) []string {
74 » » t.signalC <- now 89 » if tt, ok := t.(*timer); ok {
90 » » return clock.Tags(tt.ctx)
75 } 91 }
92 return nil
76 } 93 }
94
95 // HasTags tests if a given timer has the same tags.
96 func HasTags(t clock.Timer, tags ...string) bool {
iannucci 2016/02/10 22:30:28 HasTags(t clock.Timer, first string, rest ...strin
dnj (Google) 2016/02/11 01:26:54 Done.
97 timerTags := GetTags(t)
98 if len(timerTags) != len(tags) {
99 return false
100 }
101 for i, tag := range timerTags {
102 if tags[i] != tag {
103 return false
104 }
105 }
106 return true
107 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698