tutus-consensus/timer/timer.go

98 lines
1.6 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()
}