94 lines
3.0 KiB
Go
94 lines
3.0 KiB
Go
package raft
|
|
|
|
import (
|
|
"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 = 500 * time.Millisecond
|
|
|
|
// DefaultHeartbeatInterval is the default time to wait between heartbeats.
|
|
DefaultHeartbeatInterval = 150 * time.Millisecond
|
|
|
|
// DefaultReconnectTimeout is the default time to wait before reconnecting.
|
|
DefaultReconnectTimeout = 10 * time.Millisecond
|
|
|
|
// DefaultWaitInterval is the default time to wait log sync.
|
|
DefaultWaitInterval = 1 * 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
|
|
WaitInterval time.Duration
|
|
}
|
|
|
|
// NewClock returns a instance of Clock with defaults set.
|
|
func NewClock() *Clock {
|
|
return &Clock{
|
|
ApplyInterval: DefaultApplyInterval,
|
|
ElectionTimeout: DefaultElectionTimeout,
|
|
HeartbeatInterval: DefaultHeartbeatInterval,
|
|
ReconnectTimeout: DefaultReconnectTimeout,
|
|
WaitInterval: DefaultWaitInterval,
|
|
}
|
|
}
|
|
|
|
// 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 the election timeout.
|
|
func (c *Clock) AfterElectionTimeout() <-chan chan struct{} { return newClockChan(c.ElectionTimeout) }
|
|
|
|
// 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) }
|
|
|
|
// AfterWaitInterval returns a channel that fires after the wait interval.
|
|
func (c *Clock) AfterWaitInterval() <-chan chan struct{} { return newClockChan(c.WaitInterval) }
|
|
|
|
// HeartbeatTicker returns a Ticker that ticks every heartbeat.
|
|
func (c *Clock) HeartbeatTicker() *Ticker {
|
|
t := time.NewTicker(c.HeartbeatInterval)
|
|
return &Ticker{C: t.C, ticker: t}
|
|
}
|
|
|
|
// Now returns the current wall clock time.
|
|
func (c *Clock) Now() time.Time { return time.Now() }
|
|
|
|
// Ticker holds a channel that receives "ticks" at regular intervals.
|
|
type Ticker struct {
|
|
C <-chan time.Time
|
|
ticker *time.Ticker // realtime impl, if set
|
|
}
|
|
|
|
// Stop turns off the ticker.
|
|
func (t *Ticker) Stop() {
|
|
if t.ticker != nil {
|
|
t.ticker.Stop()
|
|
}
|
|
}
|
|
|
|
// 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{})
|
|
go func() {
|
|
time.Sleep(d)
|
|
ch <- make(chan struct{})
|
|
}()
|
|
return ch
|
|
}
|