98 lines
1.5 KiB
Go
98 lines
1.5 KiB
Go
/*
|
|
Package timer contains default implementation of [dbft.Timer] interface and provides
|
|
all necessary timer-related functionality to [dbft.DBFT] service.
|
|
*/
|
|
package timer
|
|
|
|
import (
|
|
"time"
|
|
)
|
|
|
|
type (
|
|
// Timer is a default [dbft.Timer] implementation.
|
|
Timer struct {
|
|
height uint32
|
|
view byte
|
|
s time.Time
|
|
d time.Duration
|
|
tt *time.Timer
|
|
ch chan time.Time
|
|
}
|
|
)
|
|
|
|
// New returns default Timer implementation.
|
|
func New() *Timer {
|
|
t := &Timer{
|
|
ch: make(chan time.Time, 1),
|
|
}
|
|
|
|
return t
|
|
}
|
|
|
|
// C implements Timer interface.
|
|
func (t *Timer) C() <-chan time.Time {
|
|
if t.tt == nil {
|
|
return t.ch
|
|
}
|
|
|
|
return t.tt.C
|
|
}
|
|
|
|
// Height returns current timer height.
|
|
func (t *Timer) Height() uint32 {
|
|
return t.height
|
|
}
|
|
|
|
// View return current timer view.
|
|
func (t *Timer) View() byte {
|
|
return t.view
|
|
}
|
|
|
|
// Reset implements Timer interface.
|
|
func (t *Timer) Reset(height uint32, view byte, d time.Duration) {
|
|
t.stop()
|
|
|
|
t.s = t.Now()
|
|
t.d = d
|
|
t.height = height
|
|
t.view = view
|
|
|
|
if t.d != 0 {
|
|
t.tt = time.NewTimer(t.d)
|
|
} else {
|
|
t.tt = nil
|
|
drain(t.ch)
|
|
t.ch <- t.s
|
|
}
|
|
}
|
|
|
|
func drain(ch <-chan time.Time) {
|
|
select {
|
|
case <-ch:
|
|
default:
|
|
}
|
|
}
|
|
|
|
// stop stops the Timer.
|
|
func (t *Timer) stop() {
|
|
if t.tt != nil {
|
|
t.tt.Stop()
|
|
t.tt = nil
|
|
}
|
|
}
|
|
|
|
// Extend implements Timer interface.
|
|
func (t *Timer) Extend(d time.Duration) {
|
|
t.d += d
|
|
|
|
if elapsed := time.Since(t.s); t.d > elapsed {
|
|
t.stop()
|
|
t.tt = time.NewTimer(t.d - elapsed)
|
|
}
|
|
}
|
|
|
|
// Now implements Timer interface.
|
|
func (t *Timer) Now() time.Time {
|
|
return time.Now()
|
|
}
|