forked from influxdata/influxdb
-
Notifications
You must be signed in to change notification settings - Fork 0
/
clock.go
68 lines (55 loc) · 2.33 KB
/
clock.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package raft
import (
"math/rand"
"time"
)
const (
// DefaultApplyInterval is the default time between checks to apply commands.
DefaultApplyInterval = 10 * time.Millisecond
// DefaultElectionTimeout is the default time before starting an election.
DefaultElectionTimeout = 1 * time.Second
// DefaultHeartbeatInterval is the default time to wait between heartbeats.
DefaultHeartbeatInterval = 100 * time.Millisecond
// DefaultReconnectTimeout is the default time to wait before reconnecting.
DefaultReconnectTimeout = 10 * time.Millisecond
)
// Clock implements an interface to the real-time clock.
type Clock struct {
ApplyInterval time.Duration
ElectionTimeout time.Duration
HeartbeatInterval time.Duration
ReconnectTimeout time.Duration
}
// NewClock returns a instance of Clock with defaults set.
func NewClock() *Clock {
return &Clock{
ApplyInterval: DefaultApplyInterval,
ElectionTimeout: DefaultElectionTimeout,
HeartbeatInterval: DefaultHeartbeatInterval,
ReconnectTimeout: DefaultReconnectTimeout,
}
}
// AfterApplyInterval returns a channel that fires after the apply interval.
func (c *Clock) AfterApplyInterval() <-chan chan struct{} { return newClockChan(c.ApplyInterval) }
// AfterElectionTimeout returns a channel that fires after a duration that is
// between the election timeout and double the election timeout.
func (c *Clock) AfterElectionTimeout() <-chan chan struct{} {
d := c.ElectionTimeout + time.Duration(rand.Intn(int(c.ElectionTimeout)))
return newClockChan(d)
}
// AfterHeartbeatInterval returns a channel that fires after the heartbeat interval.
func (c *Clock) AfterHeartbeatInterval() <-chan chan struct{} {
return newClockChan(c.HeartbeatInterval)
}
// AfterReconnectTimeout returns a channel that fires after the reconnection timeout.
func (c *Clock) AfterReconnectTimeout() <-chan chan struct{} { return newClockChan(c.ReconnectTimeout) }
// Now returns the current wall clock time.
func (c *Clock) Now() time.Time { return time.Now() }
// newClockChan returns a channel that sends a channel after a given duration.
// The channel being sent, over the channel that is returned, can be used to
// notify the sender when an action is done.
func newClockChan(d time.Duration) <-chan chan struct{} {
ch := make(chan chan struct{}, 1)
go func() { time.Sleep(d); ch <- make(chan struct{}) }()
return ch
}