OSDN Git Service

Hulk did something
[bytom/vapor.git] / vendor / github.com / tendermint / tmlibs / common / throttle_timer.go
1 package common
2
3 import (
4         "sync"
5         "time"
6 )
7
8 /*
9 ThrottleTimer fires an event at most "dur" after each .Set() call.
10 If a short burst of .Set() calls happens, ThrottleTimer fires once.
11 If a long continuous burst of .Set() calls happens, ThrottleTimer fires
12 at most once every "dur".
13 */
14 type ThrottleTimer struct {
15         Name string
16         Ch   chan struct{}
17         quit chan struct{}
18         dur  time.Duration
19
20         mtx   sync.Mutex
21         timer *time.Timer
22         isSet bool
23 }
24
25 func NewThrottleTimer(name string, dur time.Duration) *ThrottleTimer {
26         var ch = make(chan struct{})
27         var quit = make(chan struct{})
28         var t = &ThrottleTimer{Name: name, Ch: ch, dur: dur, quit: quit}
29         t.mtx.Lock()
30         t.timer = time.AfterFunc(dur, t.fireRoutine)
31         t.mtx.Unlock()
32         t.timer.Stop()
33         return t
34 }
35
36 func (t *ThrottleTimer) fireRoutine() {
37         t.mtx.Lock()
38         defer t.mtx.Unlock()
39         select {
40         case t.Ch <- struct{}{}:
41                 t.isSet = false
42         case <-t.quit:
43                 // do nothing
44         default:
45                 t.timer.Reset(t.dur)
46         }
47 }
48
49 func (t *ThrottleTimer) Set() {
50         t.mtx.Lock()
51         defer t.mtx.Unlock()
52         if !t.isSet {
53                 t.isSet = true
54                 t.timer.Reset(t.dur)
55         }
56 }
57
58 func (t *ThrottleTimer) Unset() {
59         t.mtx.Lock()
60         defer t.mtx.Unlock()
61         t.isSet = false
62         t.timer.Stop()
63 }
64
65 // For ease of .Stop()'ing services before .Start()'ing them,
66 // we ignore .Stop()'s on nil ThrottleTimers
67 func (t *ThrottleTimer) Stop() bool {
68         if t == nil {
69                 return false
70         }
71         close(t.quit)
72         t.mtx.Lock()
73         defer t.mtx.Unlock()
74         return t.timer.Stop()
75 }