forked from TrueCloudLab/frostfs-node
[#708] morph/timer: Add single tick timer
Signed-off-by: Alex Vanin <alexey@nspcc.ru>
This commit is contained in:
parent
7146afcd28
commit
67b3682348
2 changed files with 76 additions and 6 deletions
|
@ -31,6 +31,8 @@ type BlockTimer struct {
|
||||||
|
|
||||||
ps []BlockTimer
|
ps []BlockTimer
|
||||||
|
|
||||||
|
once bool
|
||||||
|
|
||||||
deltaCfg
|
deltaCfg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,6 +74,20 @@ func NewBlockTimer(dur BlockMeter, h BlockTickHandler) *BlockTimer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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 {
|
||||||
|
return &BlockTimer{
|
||||||
|
mtx: new(sync.Mutex),
|
||||||
|
dur: dur,
|
||||||
|
mul: 1,
|
||||||
|
div: 1,
|
||||||
|
h: h,
|
||||||
|
once: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// OnDelta registers handler which is executed on (mul / div * BlockMeter()) block
|
// OnDelta registers handler which is executed on (mul / div * BlockMeter()) block
|
||||||
// after basic interval reset.
|
// after basic interval reset.
|
||||||
//
|
//
|
||||||
|
@ -90,6 +106,7 @@ func (t *BlockTimer) OnDelta(mul, div uint32, h BlockTickHandler, opts ...DeltaO
|
||||||
mul: mul,
|
mul: mul,
|
||||||
div: div,
|
div: div,
|
||||||
h: h,
|
h: h,
|
||||||
|
once: t.once,
|
||||||
|
|
||||||
deltaCfg: c,
|
deltaCfg: c,
|
||||||
})
|
})
|
||||||
|
@ -157,10 +174,12 @@ func (t *BlockTimer) tick() {
|
||||||
// 2. call t.tickH(h)
|
// 2. call t.tickH(h)
|
||||||
t.h()
|
t.h()
|
||||||
|
|
||||||
|
if !t.once {
|
||||||
t.cur = 0
|
t.cur = 0
|
||||||
t.rolledBack = true
|
t.rolledBack = true
|
||||||
t.reset()
|
t.reset()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for i := range t.ps {
|
for i := range t.ps {
|
||||||
t.ps[i].tick()
|
t.ps[i].tick()
|
||||||
|
|
|
@ -108,3 +108,54 @@ func TestDeltaReset(t *testing.T) {
|
||||||
|
|
||||||
require.Equal(t, 2, detlaCallCounter)
|
require.Equal(t, 2, detlaCallCounter)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestNewOneTickTimer(t *testing.T) {
|
||||||
|
blockDur := uint32(1)
|
||||||
|
baseCallCounter := 0
|
||||||
|
|
||||||
|
bt := timer.NewOneTickTimer(timer.StaticBlockMeter(blockDur), func() {
|
||||||
|
baseCallCounter++
|
||||||
|
})
|
||||||
|
require.NoError(t, bt.Reset())
|
||||||
|
|
||||||
|
tickN(bt, 10)
|
||||||
|
require.Equal(t, 1, baseCallCounter) // happens once no matter what
|
||||||
|
|
||||||
|
t.Run("zero duration", func(t *testing.T) {
|
||||||
|
blockDur = uint32(0)
|
||||||
|
baseCallCounter = 0
|
||||||
|
|
||||||
|
bt = timer.NewOneTickTimer(timer.StaticBlockMeter(blockDur), func() {
|
||||||
|
baseCallCounter++
|
||||||
|
})
|
||||||
|
require.NoError(t, bt.Reset())
|
||||||
|
|
||||||
|
tickN(bt, 10)
|
||||||
|
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)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue