forked from TrueCloudLab/frostfs-node
[#1507] timer: Remove unused OnDelta() method
Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
This commit is contained in:
parent
a339b52a60
commit
3042490340
2 changed files with 17 additions and 198 deletions
|
@ -15,41 +15,19 @@ type BlockTickHandler func()
|
||||||
// It can tick the blocks and perform certain actions
|
// It can tick the blocks and perform certain actions
|
||||||
// on block time intervals.
|
// on block time intervals.
|
||||||
type BlockTimer struct {
|
type BlockTimer struct {
|
||||||
rolledBack bool
|
|
||||||
|
|
||||||
mtx sync.Mutex
|
mtx sync.Mutex
|
||||||
|
|
||||||
dur BlockMeter
|
dur BlockMeter
|
||||||
|
|
||||||
baseDur uint32
|
baseDur uint32
|
||||||
|
|
||||||
mul, div uint32
|
|
||||||
|
|
||||||
cur, tgt uint32
|
cur, tgt uint32
|
||||||
|
|
||||||
last uint32
|
last uint32
|
||||||
|
|
||||||
h BlockTickHandler
|
h BlockTickHandler
|
||||||
|
|
||||||
ps []BlockTimer
|
|
||||||
|
|
||||||
once bool
|
once bool
|
||||||
|
|
||||||
deltaCfg
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeltaOption is an option of delta-interval handler.
|
|
||||||
type DeltaOption func(*deltaCfg)
|
|
||||||
|
|
||||||
type deltaCfg struct {
|
|
||||||
pulse bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithPulse returns option to call delta-interval handler multiple times.
|
|
||||||
func WithPulse() DeltaOption {
|
|
||||||
return func(c *deltaCfg) {
|
|
||||||
c.pulse = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// StaticBlockMeter returns BlockMeters that always returns (d, nil).
|
// StaticBlockMeter returns BlockMeters that always returns (d, nil).
|
||||||
|
@ -65,52 +43,19 @@ func StaticBlockMeter(d uint32) BlockMeter {
|
||||||
func NewBlockTimer(dur BlockMeter, h BlockTickHandler) *BlockTimer {
|
func NewBlockTimer(dur BlockMeter, h BlockTickHandler) *BlockTimer {
|
||||||
return &BlockTimer{
|
return &BlockTimer{
|
||||||
dur: dur,
|
dur: dur,
|
||||||
mul: 1,
|
|
||||||
div: 1,
|
|
||||||
h: h,
|
h: h,
|
||||||
deltaCfg: deltaCfg{
|
|
||||||
pulse: true,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewOneTickTimer creates a new BlockTimer that ticks only once.
|
// NewOneTickTimer creates a new BlockTimer that ticks only once.
|
||||||
//
|
|
||||||
// Do not use delta handlers with pulse in this timer.
|
|
||||||
func NewOneTickTimer(dur BlockMeter, h BlockTickHandler) *BlockTimer {
|
func NewOneTickTimer(dur BlockMeter, h BlockTickHandler) *BlockTimer {
|
||||||
return &BlockTimer{
|
return &BlockTimer{
|
||||||
dur: dur,
|
dur: dur,
|
||||||
mul: 1,
|
|
||||||
div: 1,
|
|
||||||
h: h,
|
h: h,
|
||||||
once: true,
|
once: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// OnDelta registers handler which is executed on (mul / div * BlockMeter()) block
|
|
||||||
// after basic interval reset.
|
|
||||||
//
|
|
||||||
// If WithPulse option is provided, handler is executed (mul / div * BlockMeter()) block
|
|
||||||
// during base interval.
|
|
||||||
func (t *BlockTimer) OnDelta(mul, div uint32, h BlockTickHandler, opts ...DeltaOption) {
|
|
||||||
c := deltaCfg{
|
|
||||||
pulse: false,
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := range opts {
|
|
||||||
opts[i](&c)
|
|
||||||
}
|
|
||||||
|
|
||||||
t.ps = append(t.ps, BlockTimer{
|
|
||||||
mul: mul,
|
|
||||||
div: div,
|
|
||||||
h: h,
|
|
||||||
once: t.once,
|
|
||||||
|
|
||||||
deltaCfg: c,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset resets previous ticks of the BlockTimer.
|
// Reset resets previous ticks of the BlockTimer.
|
||||||
//
|
//
|
||||||
// Returns BlockMeter's error upon occurrence.
|
// Returns BlockMeter's error upon occurrence.
|
||||||
|
@ -124,29 +69,18 @@ func (t *BlockTimer) Reset() error {
|
||||||
|
|
||||||
t.resetWithBaseInterval(d)
|
t.resetWithBaseInterval(d)
|
||||||
|
|
||||||
for i := range t.ps {
|
|
||||||
t.ps[i].resetWithBaseInterval(d)
|
|
||||||
}
|
|
||||||
|
|
||||||
t.mtx.Unlock()
|
t.mtx.Unlock()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *BlockTimer) resetWithBaseInterval(d uint32) {
|
func (t *BlockTimer) resetWithBaseInterval(d uint32) {
|
||||||
t.rolledBack = false
|
|
||||||
t.baseDur = d
|
t.baseDur = d
|
||||||
t.reset()
|
t.reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *BlockTimer) reset() {
|
func (t *BlockTimer) reset() {
|
||||||
mul, div := t.mul, t.div
|
delta := t.baseDur
|
||||||
|
|
||||||
if !t.pulse && t.rolledBack && mul < div {
|
|
||||||
mul, div = 1, 1
|
|
||||||
}
|
|
||||||
|
|
||||||
delta := mul * t.baseDur / div
|
|
||||||
if delta == 0 {
|
if delta == 0 {
|
||||||
delta = 1
|
delta = 1
|
||||||
}
|
}
|
||||||
|
@ -180,12 +114,7 @@ func (t *BlockTimer) tick(h uint32) {
|
||||||
|
|
||||||
if !t.once {
|
if !t.once {
|
||||||
t.cur = 0
|
t.cur = 0
|
||||||
t.rolledBack = true
|
|
||||||
t.reset()
|
t.reset()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := range t.ps {
|
|
||||||
t.ps[i].tick(h)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,85 +63,6 @@ func TestBlockTimer(t *testing.T) {
|
||||||
tickN(bt, intervalNum*blockDur)
|
tickN(bt, intervalNum*blockDur)
|
||||||
|
|
||||||
require.Equal(t, intervalNum, uint32(baseCallCounter))
|
require.Equal(t, intervalNum, uint32(baseCallCounter))
|
||||||
|
|
||||||
// add half-interval handler
|
|
||||||
halfCallCounter := uint32(0)
|
|
||||||
|
|
||||||
bt.OnDelta(1, 2, func() {
|
|
||||||
halfCallCounter++
|
|
||||||
})
|
|
||||||
|
|
||||||
// add double interval handler
|
|
||||||
doubleCallCounter := uint32(0)
|
|
||||||
|
|
||||||
bt.OnDelta(2, 1, func() {
|
|
||||||
doubleCallCounter++
|
|
||||||
})
|
|
||||||
|
|
||||||
require.NoError(t, bt.Reset())
|
|
||||||
|
|
||||||
baseCallCounter = 0
|
|
||||||
intervalNum = 20
|
|
||||||
|
|
||||||
tickN(bt, intervalNum*blockDur)
|
|
||||||
|
|
||||||
require.Equal(t, intervalNum, uint32(halfCallCounter))
|
|
||||||
require.Equal(t, intervalNum, uint32(baseCallCounter))
|
|
||||||
require.Equal(t, intervalNum/2, uint32(doubleCallCounter))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDeltaPulse(t *testing.T) {
|
|
||||||
blockDur := uint32(9)
|
|
||||||
baseCallCounter := uint32(0)
|
|
||||||
|
|
||||||
bt := timer.NewBlockTimer(timer.StaticBlockMeter(blockDur), func() {
|
|
||||||
baseCallCounter++
|
|
||||||
})
|
|
||||||
|
|
||||||
deltaCallCounter := uint32(0)
|
|
||||||
|
|
||||||
div := uint32(3)
|
|
||||||
|
|
||||||
bt.OnDelta(1, div, func() {
|
|
||||||
deltaCallCounter++
|
|
||||||
}, timer.WithPulse())
|
|
||||||
|
|
||||||
require.NoError(t, bt.Reset())
|
|
||||||
|
|
||||||
intervalNum := uint32(7)
|
|
||||||
|
|
||||||
tickN(bt, intervalNum*blockDur)
|
|
||||||
|
|
||||||
require.Equal(t, intervalNum, uint32(baseCallCounter))
|
|
||||||
require.Equal(t, intervalNum*div, uint32(deltaCallCounter))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDeltaReset(t *testing.T) {
|
|
||||||
blockDur := uint32(6)
|
|
||||||
baseCallCounter := 0
|
|
||||||
|
|
||||||
bt := timer.NewBlockTimer(timer.StaticBlockMeter(blockDur), func() {
|
|
||||||
baseCallCounter++
|
|
||||||
})
|
|
||||||
|
|
||||||
detlaCallCounter := 0
|
|
||||||
|
|
||||||
bt.OnDelta(1, 3, func() {
|
|
||||||
detlaCallCounter++
|
|
||||||
})
|
|
||||||
|
|
||||||
require.NoError(t, bt.Reset())
|
|
||||||
|
|
||||||
tickN(bt, 6)
|
|
||||||
|
|
||||||
require.Equal(t, 1, baseCallCounter)
|
|
||||||
require.Equal(t, 1, detlaCallCounter)
|
|
||||||
|
|
||||||
require.NoError(t, bt.Reset())
|
|
||||||
|
|
||||||
tickN(bt, 3)
|
|
||||||
|
|
||||||
require.Equal(t, 2, detlaCallCounter)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewOneTickTimer(t *testing.T) {
|
func TestNewOneTickTimer(t *testing.T) {
|
||||||
|
@ -168,82 +89,51 @@ func TestNewOneTickTimer(t *testing.T) {
|
||||||
tickN(bt, 10)
|
tickN(bt, 10)
|
||||||
require.Equal(t, 1, baseCallCounter)
|
require.Equal(t, 1, baseCallCounter)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("delta without pulse", func(t *testing.T) {
|
|
||||||
blockDur = uint32(10)
|
|
||||||
baseCallCounter = 0
|
|
||||||
|
|
||||||
bt = timer.NewOneTickTimer(timer.StaticBlockMeter(blockDur), func() {
|
|
||||||
baseCallCounter++
|
|
||||||
})
|
|
||||||
|
|
||||||
detlaCallCounter := 0
|
|
||||||
|
|
||||||
bt.OnDelta(1, 10, func() {
|
|
||||||
detlaCallCounter++
|
|
||||||
})
|
|
||||||
|
|
||||||
require.NoError(t, bt.Reset())
|
|
||||||
|
|
||||||
tickN(bt, 10)
|
|
||||||
require.Equal(t, 1, baseCallCounter)
|
|
||||||
require.Equal(t, 1, detlaCallCounter)
|
|
||||||
|
|
||||||
tickN(bt, 10) // 10 more ticks must not affect counters
|
|
||||||
require.Equal(t, 1, baseCallCounter)
|
|
||||||
require.Equal(t, 1, detlaCallCounter)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBlockTimer_TickSameHeight(t *testing.T) {
|
func TestBlockTimer_TickSameHeight(t *testing.T) {
|
||||||
var baseCounter, deltaCounter int
|
var baseCounter int
|
||||||
|
|
||||||
blockDur := uint32(2)
|
blockDur := uint32(2)
|
||||||
bt := timer.NewBlockTimer(
|
bt := timer.NewBlockTimer(
|
||||||
func() (uint32, error) { return blockDur, nil },
|
func() (uint32, error) { return blockDur, nil },
|
||||||
func() { baseCounter++ })
|
func() { baseCounter++ })
|
||||||
bt.OnDelta(2, 1, func() {
|
|
||||||
deltaCounter++
|
|
||||||
})
|
|
||||||
require.NoError(t, bt.Reset())
|
require.NoError(t, bt.Reset())
|
||||||
|
|
||||||
check := func(t *testing.T, h uint32, base, delta int) {
|
check := func(t *testing.T, h uint32, base int) {
|
||||||
for range 2 * int(blockDur) {
|
for range 2 * int(blockDur) {
|
||||||
bt.Tick(h)
|
bt.Tick(h)
|
||||||
require.Equal(t, base, baseCounter)
|
require.Equal(t, base, baseCounter)
|
||||||
require.Equal(t, delta, deltaCounter)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
check(t, 1, 0, 0)
|
check(t, 1, 0)
|
||||||
check(t, 2, 1, 0)
|
check(t, 2, 1)
|
||||||
check(t, 3, 1, 0)
|
check(t, 3, 1)
|
||||||
check(t, 4, 2, 1)
|
check(t, 4, 2)
|
||||||
|
|
||||||
t.Run("works the same way after `Reset()`", func(t *testing.T) {
|
t.Run("works the same way after `Reset()`", func(t *testing.T) {
|
||||||
t.Run("same block duration", func(t *testing.T) {
|
t.Run("same block duration", func(t *testing.T) {
|
||||||
require.NoError(t, bt.Reset())
|
require.NoError(t, bt.Reset())
|
||||||
baseCounter = 0
|
baseCounter = 0
|
||||||
deltaCounter = 0
|
|
||||||
|
|
||||||
check(t, 1, 0, 0)
|
check(t, 1, 0)
|
||||||
check(t, 2, 1, 0)
|
check(t, 2, 1)
|
||||||
check(t, 3, 1, 0)
|
check(t, 3, 1)
|
||||||
check(t, 4, 2, 1)
|
check(t, 4, 2)
|
||||||
})
|
})
|
||||||
t.Run("different block duration", func(t *testing.T) {
|
t.Run("different block duration", func(t *testing.T) {
|
||||||
blockDur = 3
|
blockDur = 3
|
||||||
|
|
||||||
require.NoError(t, bt.Reset())
|
require.NoError(t, bt.Reset())
|
||||||
baseCounter = 0
|
baseCounter = 0
|
||||||
deltaCounter = 0
|
|
||||||
|
|
||||||
check(t, 1, 0, 0)
|
check(t, 1, 0)
|
||||||
check(t, 2, 0, 0)
|
check(t, 2, 0)
|
||||||
check(t, 3, 1, 0)
|
check(t, 3, 1)
|
||||||
check(t, 4, 1, 0)
|
check(t, 4, 1)
|
||||||
check(t, 5, 1, 0)
|
check(t, 5, 1)
|
||||||
check(t, 6, 2, 1)
|
check(t, 6, 2)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue