From 0b6798acb5303caebd4427259fa663151f770dd8 Mon Sep 17 00:00:00 2001 From: hinego <89022212+hinego@users.noreply.github.com> Date: Mon, 20 Mar 2023 10:00:55 +0800 Subject: [PATCH] add `Quick` mode for gtimer (#2488) --- os/gtimer/gtimer.go | 1 + os/gtimer/gtimer_timer.go | 16 ++++++++--- os/gtimer/gtimer_z_unit_entry_test.go | 21 +++++++++++++++ os/gtimer/gtimer_z_unit_timer_test.go | 38 +++++++++++++++++++++++++++ 4 files changed, 73 insertions(+), 3 deletions(-) diff --git a/os/gtimer/gtimer.go b/os/gtimer/gtimer.go index 89e201f6c4d..7988d4d2507 100644 --- a/os/gtimer/gtimer.go +++ b/os/gtimer/gtimer.go @@ -42,6 +42,7 @@ type Timer struct { // TimerOptions is the configuration object for Timer. type TimerOptions struct { Interval time.Duration // Interval is the interval escaped of the timer. + Quick bool // Quick is used for quick timer, which means the timer will not wait for the first interval to be elapsed. } // internalPanic is the custom panic for internal usage. diff --git a/os/gtimer/gtimer_timer.go b/os/gtimer/gtimer_timer.go index 7badd0c2b5c..2792cc442cf 100644 --- a/os/gtimer/gtimer_timer.go +++ b/os/gtimer/gtimer_timer.go @@ -22,6 +22,9 @@ func New(options ...TimerOptions) *Timer { } if len(options) > 0 { t.options = options[0] + if t.options.Interval == 0 { + t.options.Interval = defaultInterval + } } else { t.options = DefaultOptions() } @@ -166,7 +169,8 @@ type createEntryInput struct { // createEntry creates and adds a timing job to the timer. func (t *Timer) createEntry(in createEntryInput) *Entry { var ( - infinite = false + infinite = false + nextTicks int64 ) if in.Times <= 0 { infinite = true @@ -179,9 +183,15 @@ func (t *Timer) createEntry(in createEntryInput) *Entry { // then sets it to one tick, which means it will be run in one interval. intervalTicksOfJob = 1 } - var ( + if t.options.Quick { + // If the quick mode is enabled, which means it will be run right now. + // Don't need to wait for the first interval. + nextTicks = t.ticks.Val() + } else { nextTicks = t.ticks.Val() + intervalTicksOfJob - entry = &Entry{ + } + var ( + entry = &Entry{ job: in.Job, ctx: in.Ctx, timer: t, diff --git a/os/gtimer/gtimer_z_unit_entry_test.go b/os/gtimer/gtimer_z_unit_entry_test.go index 3aa4a8e0f1f..08a1a794b04 100644 --- a/os/gtimer/gtimer_z_unit_entry_test.go +++ b/os/gtimer/gtimer_z_unit_entry_test.go @@ -60,6 +60,27 @@ func TestJob_Singleton(t *testing.T) { }) } +func TestJob_SingletonQuick(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + timer := gtimer.New(gtimer.TimerOptions{ + Quick: true, + }) + array := garray.New(true) + job := timer.Add(ctx, 5*time.Second, func(ctx context.Context) { + array.Append(1) + time.Sleep(10 * time.Second) + }) + t.Assert(job.IsSingleton(), false) + job.SetSingleton(true) + t.Assert(job.IsSingleton(), true) + time.Sleep(250 * time.Millisecond) + t.Assert(array.Len(), 1) + + time.Sleep(250 * time.Millisecond) + t.Assert(array.Len(), 1) + }) +} + func TestJob_SetTimes(t *testing.T) { gtest.C(t, func(t *gtest.T) { timer := gtimer.New() diff --git a/os/gtimer/gtimer_z_unit_timer_test.go b/os/gtimer/gtimer_z_unit_timer_test.go index 5a564e90ed9..0504c2b8c3c 100644 --- a/os/gtimer/gtimer_z_unit_timer_test.go +++ b/os/gtimer/gtimer_z_unit_timer_test.go @@ -103,6 +103,44 @@ func TestTimer_AddSingleton(t *testing.T) { }) } +func TestTimer_AddSingletonWithQuick(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + timer := gtimer.New(gtimer.TimerOptions{ + Interval: 100 * time.Millisecond, + Quick: true, + }) + array := garray.New(true) + timer.AddSingleton(ctx, 5*time.Second, func(ctx context.Context) { + array.Append(1) + time.Sleep(10 * time.Second) + }) + time.Sleep(250 * time.Millisecond) + t.Assert(array.Len(), 1) + + time.Sleep(500 * time.Millisecond) + t.Assert(array.Len(), 1) + }) +} + +func TestTimer_AddSingletonWithoutQuick(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + timer := gtimer.New(gtimer.TimerOptions{ + Interval: 100 * time.Millisecond, + Quick: false, + }) + array := garray.New(true) + timer.AddSingleton(ctx, 5*time.Second, func(ctx context.Context) { + array.Append(1) + time.Sleep(10 * time.Second) + }) + time.Sleep(250 * time.Millisecond) + t.Assert(array.Len(), 0) + + time.Sleep(500 * time.Millisecond) + t.Assert(array.Len(), 0) + }) +} + func TestTimer_AddOnce(t *testing.T) { gtest.C(t, func(t *gtest.T) { timer := gtimer.New()