From 7258ef113a0daa8478dc86afd41859dc8e659239 Mon Sep 17 00:00:00 2001 From: Ming Deng Date: Sun, 19 Jul 2020 14:34:57 +0000 Subject: [PATCH] Store nearest error info --- toolbox/task.go | 12 +++++++++--- toolbox/task_test.go | 22 ++++++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/toolbox/task.go b/toolbox/task.go index d2a94ba9..c902fdfc 100644 --- a/toolbox/task.go +++ b/toolbox/task.go @@ -102,6 +102,8 @@ type taskerr struct { } // Task task struct +// It's not a thread-safe structure. +// Only nearest errors will be saved in ErrList type Task struct { Taskname string Spec *Schedule @@ -111,6 +113,7 @@ type Task struct { Next time.Time Errlist []*taskerr // like errtime:errinfo ErrLimit int // max length for the errlist, 0 stand for no limit + errCnt int // records the error count during the execution } // NewTask add new task with name, time and func @@ -119,8 +122,11 @@ func NewTask(tname string, spec string, f TaskFunc) *Task { task := &Task{ Taskname: tname, DoFunc: f, + // Make configurable ErrLimit: 100, SpecStr: spec, + // we only store the pointer, so it won't use too many space + Errlist: make([]*taskerr, 100, 100), } task.SetCron(spec) return task @@ -144,9 +150,9 @@ func (t *Task) GetStatus() string { func (t *Task) Run() error { err := t.DoFunc() if err != nil { - if t.ErrLimit > 0 && t.ErrLimit > len(t.Errlist) { - t.Errlist = append(t.Errlist, &taskerr{t: t.Next, errinfo: err.Error()}) - } + index := t.errCnt % t.ErrLimit + t.Errlist[index] = &taskerr{t: t.Next, errinfo: err.Error()} + t.errCnt++ } return err } diff --git a/toolbox/task_test.go b/toolbox/task_test.go index 596bc9c5..3a4cce2f 100644 --- a/toolbox/task_test.go +++ b/toolbox/task_test.go @@ -15,10 +15,13 @@ package toolbox import ( + "errors" "fmt" "sync" "testing" "time" + + "github.com/stretchr/testify/assert" ) func TestParse(t *testing.T) { @@ -53,6 +56,25 @@ func TestSpec(t *testing.T) { } } +func TestTask_Run(t *testing.T) { + cnt := -1 + task := func() error { + cnt ++ + fmt.Printf("Hello, world! %d \n", cnt) + return errors.New(fmt.Sprintf("Hello, world! %d", cnt)) + } + tk := NewTask("taska", "0/30 * * * * *", task) + for i := 0; i < 200 ; i ++ { + e := tk.Run() + assert.NotNil(t, e) + } + + l := tk.Errlist + assert.Equal(t, 100, len(l)) + assert.Equal(t, "Hello, world! 100", l[0].errinfo) + assert.Equal(t, "Hello, world! 101", l[1].errinfo) +} + func wait(wg *sync.WaitGroup) chan bool { ch := make(chan bool) go func() {