From 842da421cba3b92b57ec167f1be21edbcab7249f Mon Sep 17 00:00:00 2001 From: guonaihong Date: Fri, 16 Feb 2024 14:15:57 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: guonaihong --- min_heap.go | 3 + min_heap_node.go | 3 + min_heap_node_test.go | 4 ++ min_heap_test.go | 3 + option.go | 7 ++- t_test.go | 3 + time_wheel.go | 3 + time_wheel_node.go | 5 +- time_wheel_test.go | 3 + time_wheel_utils.go | 3 + timer.go | 6 +- timer_test.go | 122 ++++++++++++++++++++++++++++++++++++-- timer_wheel_utils_test.go | 3 + 13 files changed, 158 insertions(+), 10 deletions(-) diff --git a/min_heap.go b/min_heap.go index 1b31aed..5f79ff3 100644 --- a/min_heap.go +++ b/min_heap.go @@ -1,3 +1,6 @@ +// Copyright 2020-2024 guonaihong, antlabs. All rights reserved. +// +// mit license package timer import ( diff --git a/min_heap_node.go b/min_heap_node.go index 3fd922c..760d645 100644 --- a/min_heap_node.go +++ b/min_heap_node.go @@ -1,3 +1,6 @@ +// Copyright 2020-2024 guonaihong, antlabs. All rights reserved. +// +// mit license package timer import ( diff --git a/min_heap_node_test.go b/min_heap_node_test.go index 1c88f22..6489d43 100644 --- a/min_heap_node_test.go +++ b/min_heap_node_test.go @@ -1,3 +1,7 @@ +// Copyright 2020-2024 guonaihong, antlabs. All rights reserved. +// +// mit license + package timer import ( diff --git a/min_heap_test.go b/min_heap_test.go index 792a749..e0788c0 100644 --- a/min_heap_test.go +++ b/min_heap_test.go @@ -1,3 +1,6 @@ +// Copyright 2020-2024 guonaihong, antlabs. All rights reserved. +// +// mit license package timer import ( diff --git a/option.go b/option.go index a70db74..b2606b6 100644 --- a/option.go +++ b/option.go @@ -1,3 +1,6 @@ +// Copyright 2020-2024 guonaihong, antlabs. All rights reserved. +// +// mit license package timer type option struct { @@ -21,14 +24,14 @@ func WithMinHeap() Option { } } -//TODO +// TODO func WithSkipList() Option { return func(o *option) { o.skiplist = true } } -//TODO +// TODO func WithRbtree() Option { return func(o *option) { o.rbtree = true diff --git a/t_test.go b/t_test.go index 2dbdcf6..90b7b9a 100644 --- a/t_test.go +++ b/t_test.go @@ -1,3 +1,6 @@ +// Copyright 2020-2024 guonaihong, antlabs. All rights reserved. +// +// mit license package timer import ( diff --git a/time_wheel.go b/time_wheel.go index b6d0580..4d6e01a 100644 --- a/time_wheel.go +++ b/time_wheel.go @@ -1,3 +1,6 @@ +// Copyright 2020-2024 guonaihong, antlabs. All rights reserved. +// +// mit license package timer import ( diff --git a/time_wheel_node.go b/time_wheel_node.go index b7aea4d..55e33c9 100644 --- a/time_wheel_node.go +++ b/time_wheel_node.go @@ -1,3 +1,6 @@ +// Copyright 2020-2024 guonaihong, antlabs. All rights reserved. +// +// mit license package timer import ( @@ -105,5 +108,5 @@ func (t *timeNode) Reset(expire time.Duration) { expire = expire/(time.Millisecond*10) + time.Duration(jiffies) t.expire = uint64(expire) - t.root.add(t, atomic.LoadUint64(&t.root.jiffies)) + t.root.add(t, jiffies) } diff --git a/time_wheel_test.go b/time_wheel_test.go index e254383..520f04f 100644 --- a/time_wheel_test.go +++ b/time_wheel_test.go @@ -1,3 +1,6 @@ +// Copyright 2020-2024 guonaihong, antlabs. All rights reserved. +// +// mit license package timer import ( diff --git a/time_wheel_utils.go b/time_wheel_utils.go index cc97794..66f15bc 100644 --- a/time_wheel_utils.go +++ b/time_wheel_utils.go @@ -1,3 +1,6 @@ +// Copyright 2020-2024 guonaihong, antlabs. All rights reserved. +// +// mit license package timer import "time" diff --git a/timer.go b/timer.go index 6cc6f68..f36d622 100644 --- a/timer.go +++ b/timer.go @@ -1,3 +1,6 @@ +// Copyright 2020-2024 guonaihong, antlabs. All rights reserved. +// +// mit license package timer import "time" @@ -27,7 +30,8 @@ type Timer interface { // 停止单个定时器 type TimeNoder interface { Stop() - Reset(d time.Duration) + // 重置时间器 + Reset(expire time.Duration) } // 定时器构造函数 diff --git a/timer_test.go b/timer_test.go index a44947f..7936bc6 100644 --- a/timer_test.go +++ b/timer_test.go @@ -1,7 +1,11 @@ +// Copyright 2020-2024 guonaihong, antlabs. All rights reserved. +// +// mit license package timer import ( "log" + "sync" "sync/atomic" "testing" "time" @@ -34,7 +38,7 @@ func Test_ScheduleFunc(t *testing.T) { func Test_AfterFunc(t *testing.T) { tm := NewTimer() - + go tm.Run() log.Printf("start\n") count := uint32(0) @@ -60,11 +64,9 @@ func Test_AfterFunc(t *testing.T) { tm.AfterFunc(time.Hour*24*365*12, nil) */ - go func() { - time.Sleep(time.Second + time.Millisecond*100) - tm.Stop() - }() - tm.Run() + time.Sleep(time.Second + time.Millisecond*100) + tm.Stop() + if count != 2 { t.Errorf("count:%d != 2\n", count) } @@ -107,3 +109,111 @@ func Test_Node_Stop(t *testing.T) { } } + +// 测试重置定时器 +func Test_Reset(t *testing.T) { + t.Run("min heap reset", func(t *testing.T) { + + tm := NewTimer(WithMinHeap()) + + go tm.Run() + count := int32(0) + + tc := make(chan time.Duration, 2) + + var mu sync.Mutex + isClose := false + now := time.Now() + node1 := tm.AfterFunc(time.Millisecond*100, func() { + + mu.Lock() + atomic.AddInt32(&count, 1) + if atomic.LoadInt32(&count) <= 2 && !isClose { + tc <- time.Since(now) + } + mu.Unlock() + }) + + node2 := tm.AfterFunc(time.Millisecond*100, func() { + mu.Lock() + atomic.AddInt32(&count, 1) + if atomic.LoadInt32(&count) <= 2 && !isClose { + tc <- time.Since(now) + } + mu.Unlock() + }) + node1.Reset(time.Millisecond) + node2.Reset(time.Millisecond) + + time.Sleep(time.Millisecond * 3) + mu.Lock() + isClose = true + close(tc) + node1.Stop() + node2.Stop() + mu.Unlock() + for tv := range tc { + if tv < time.Millisecond || tv > 2*time.Millisecond { + t.Errorf("tc < time.Millisecond tc > 2*time.Millisecond") + + } + } + if atomic.LoadInt32(&count) != 2 { + t.Errorf("count:%d != 2", atomic.LoadInt32(&count)) + } + + }) + + t.Run("time wheel reset", func(t *testing.T) { + tm := NewTimer() + + go func() { + tm.Run() + }() + + count := int32(0) + + tc := make(chan time.Duration, 2) + + var mu sync.Mutex + isClose := false + now := time.Now() + node1 := tm.AfterFunc(time.Millisecond*10, func() { + + mu.Lock() + atomic.AddInt32(&count, 1) + if atomic.LoadInt32(&count) <= 2 && !isClose { + tc <- time.Since(now) + } + mu.Unlock() + }) + + node2 := tm.AfterFunc(time.Millisecond*10, func() { + mu.Lock() + atomic.AddInt32(&count, 1) + if atomic.LoadInt32(&count) <= 2 && !isClose { + tc <- time.Since(now) + } + mu.Unlock() + }) + + node1.Reset(time.Millisecond * 20) + node2.Reset(time.Millisecond * 20) + + time.Sleep(time.Millisecond * 40) + mu.Lock() + isClose = true + close(tc) + node1.Stop() + node2.Stop() + mu.Unlock() + for tv := range tc { + if tv < time.Millisecond*20 || tv > 2*time.Millisecond*20 { + t.Errorf("tc < time.Millisecond tc > 2*time.Millisecond") + } + } + if atomic.LoadInt32(&count) != 2 { + t.Errorf("count:%d != 2", atomic.LoadInt32(&count)) + } + }) +} diff --git a/timer_wheel_utils_test.go b/timer_wheel_utils_test.go index 69744c7..0c4cdd6 100644 --- a/timer_wheel_utils_test.go +++ b/timer_wheel_utils_test.go @@ -1,3 +1,6 @@ +// Copyright 2020-2024 guonaihong, antlabs. All rights reserved. +// +// mit license package timer import (