Skip to content

Commit

Permalink
[#xxx] morph/timer: Add single tick timer
Browse files Browse the repository at this point in the history
Signed-off-by: Alex Vanin <[email protected]>
  • Loading branch information
alexvanin committed Jul 21, 2021
1 parent 83a5e12 commit 4ab91ae
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 6 deletions.
31 changes: 25 additions & 6 deletions pkg/morph/timer/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ type BlockTimer struct {

ps []BlockTimer

once bool

deltaCfg
}

Expand Down Expand Up @@ -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
// after basic interval reset.
//
Expand All @@ -87,9 +103,10 @@ func (t *BlockTimer) OnDelta(mul, div uint32, h BlockTickHandler, opts ...DeltaO
}

t.ps = append(t.ps, BlockTimer{
mul: mul,
div: div,
h: h,
mul: mul,
div: div,
h: h,
once: t.once,

deltaCfg: c,
})
Expand Down Expand Up @@ -157,9 +174,11 @@ func (t *BlockTimer) tick() {
// 2. call t.tickH(h)
t.h()

t.cur = 0
t.rolledBack = true
t.reset()
if !t.once {
t.cur = 0
t.rolledBack = true
t.reset()
}
}

for i := range t.ps {
Expand Down
51 changes: 51 additions & 0 deletions pkg/morph/timer/block_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,54 @@ func TestDeltaReset(t *testing.T) {

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)
})
}

0 comments on commit 4ab91ae

Please sign in to comment.