diff --git a/crontab.go b/crontab.go index e471def..4c22415 100644 --- a/crontab.go +++ b/crontab.go @@ -19,9 +19,20 @@ type randLR struct { left, right int } +type randLRC struct { + randLR + count int +} + type hInterval struct { - PlanFail []randLR - PlanNormal []randLR + PlanFailCount []randLRC + PlanTrueCount []randLRC + + PlanFail []randLR + PlanTrue []randLR + + TrueCount int + FailCount int Count int ConstCount int @@ -221,14 +232,29 @@ func (cron *Crontab) linuxTimeUp() bool { func (cron *Crontab) intervalCalculateNextTime(now time.Time) { iv := cron.interval.Cursor().GetValue().(hInterval) isecond := 0 - if cron.lastStatus == false && len(iv.PlanFail) > 0 { - idx := randomdata.Number(len(iv.PlanFail)) - lr := iv.PlanFail[idx] - isecond = randomdata.Number(lr.left, lr.right+1) - log.Println("fail time ", isecond) + + if cron.lastStatus { + iv.TrueCount++ + iv.FailCount = 0 } else { - idx := randomdata.Number(len(iv.PlanNormal)) - lr := iv.PlanNormal[idx] + iv.FailCount++ + iv.TrueCount = 0 + } + + if cron.lastStatus == false { + + if len(iv.PlanFailCount) > 0 { + + } else if len(iv.PlanFail) > 0 { + idx := randomdata.Number(len(iv.PlanFail)) + lr := iv.PlanFail[idx] + isecond = randomdata.Number(lr.left, lr.right+1) + } + + log.Println("fail:", iv.FailCount, "count time wait:", isecond, "s") + } else { + idx := randomdata.Number(len(iv.PlanTrue)) + lr := iv.PlanTrue[idx] isecond = randomdata.Number(lr.left, lr.right+1) } @@ -374,13 +400,37 @@ func parseIntervalString(crontab string) []interface{} { switch FN[0] { case 'f', 'F': - fvalue := FN[1:] - interval.PlanFail = append(interval.PlanFail, parseRandLR(fvalue)) - case 'n': - value := FN[1:] - interval.PlanNormal = append(interval.PlanNormal, parseRandLR(value)) + scharIndex := strings.Index(FN, "?") + if scharIndex != -1 { + fc := FN[0:scharIndex] + flr := FN[scharIndex+1:] + interval.PlanFailCount = append(interval.PlanFailCount, parseRandLRC(fc, flr)) + } else { + fvalue := FN[1:] + interval.PlanFail = append(interval.PlanFail, parseRandLR(fvalue)) + } + case 't', 'T': + scharIndex := strings.Index(FN, "?") + if scharIndex != -1 { + tc := FN[0:scharIndex] + tlr := FN[scharIndex+1:] + interval.PlanTrueCount = append(interval.PlanTrueCount, parseRandLRC(tc, tlr)) + } else { + tvalue := FN[1:] + interval.PlanTrue = append(interval.PlanTrue, parseRandLR(tvalue)) + } + default: - interval.PlanNormal = append(interval.PlanNormal, parseRandLR(FN)) + FN = "t" + FN + scharIndex := strings.Index(FN, "?") + if scharIndex != -1 { + tc := FN[0:scharIndex] + tlr := FN[scharIndex+1:] + interval.PlanTrueCount = append(interval.PlanTrueCount, parseRandLRC(tc, tlr)) + } else { + tvalue := FN[1:] + interval.PlanTrue = append(interval.PlanTrue, parseRandLR(tvalue)) + } } } @@ -391,11 +441,15 @@ func parseIntervalString(crontab string) []interface{} { return result } -func parseRandLR(value string) randLR { - vlen := len(value) - lastchar := value[vlen-1] +func parseRandLRC(fc, flr string) randLRC { + return randLRC{count: getInt(fc[1:]), randLR: parseRandLR(flr)} +} - lr := strings.Split(value, "-") +func parseRandLR(lrvalue string) randLR { + vlen := len(lrvalue) + lastchar := lrvalue[vlen-1] + + lr := strings.Split(lrvalue, "-") switch len(lr) { case 1: lr := randLR{parseTimeValue(lr[0], lastchar), parseTimeValue(lr[0], lastchar)} diff --git a/crontab_test.go b/crontab_test.go index 3a126ed..f43cf74 100644 --- a/crontab_test.go +++ b/crontab_test.go @@ -36,7 +36,7 @@ func TestParseCrontab(t *testing.T) { func TestParseInterval(t *testing.T) { //crontab := "0-5/2,7-30/3,30,35,40-^1 * * * *" //(秒) 分 时 号(每月的多少号, 要注意月可可能性) 星期几(每个星期的) /每 ,列表 -范围 - //crontab := "f1-2|1-3|5-8x5,f1|10m,10-15,f1" + //crontab := "f1-2|1-3|5-8x5,f1|10m,10-15,f22?15-12" crontab := "2" cron := NewCrontab(crontab) now := time.Now() @@ -63,7 +63,7 @@ func TestParseIntervalPlus(t *testing.T) { // crondata := NewCrontab("*22 * * * *") //crontab := "0-5/2,7-30/3,30,35,40-^1 * * * *" //(秒) 分 时 号(每月的多少号, 要注意月可可能性) 星期几(每个星期的) /每 ,列表 -范围 - //crontab := "f1-2|1-3|5-8x5,f1|10m,10-15,f1" + //crontab := "f1-2|1-3|5-8x5,f1|10m,10-15,f1" ^代表往后算 ^5 2月份就代表 28-4=24 f代表失败后1-2秒设置 由SetStatus控制 t 相反默认不写前缀为t } diff --git a/priority_list.go b/priority_list.go new file mode 100644 index 0000000..e4580c8 --- /dev/null +++ b/priority_list.go @@ -0,0 +1,118 @@ +package crontab + +import ( + "github.com/davecgh/go-spew/spew" +) + +// INode 比较的必须继承的接口 +type INode interface { + Compare(v INode) bool + + // GetValue 获取值 + GetValue() interface{} + // SetValue 设置值 + SetValue(v interface{}) + + GetPrev() INode + SetPrev(INode) + GetNext() INode + SetNext(INode) +} + +// Node 优先链表的节点 +type Node struct { + INode + prev, next INode + // isrelease bool + value interface{} +} + +// NewNode 创建一个PriorityList 节点 +func NewNode(v interface{}) *Node { + n := new(Node) + n.SetValue(v) + return n +} + +// GetValue 获取值 +func (node *Node) GetValue() interface{} { + return node.value +} + +// SetValue 设置值 +func (node *Node) SetValue(v interface{}) { + node.value = v +} + +// GetPrev 获取left值 +func (node *Node) GetPrev() INode { + return node.prev +} + +// SetPrev 设置left值 +func (node *Node) SetPrev(n INode) { + node.prev = n +} + +// GetNext 设置right值 +func (node *Node) GetNext() INode { + return node.next +} + +// SetNext 获取left值 +func (node *Node) SetNext(n INode) { + node.next = n +} + +// PriorityList 优先列表 +type PriorityList struct { + head INode +} + +func (pl *PriorityList) String() string { + content := "[" + + cur := pl.head + for cur != nil { + content += spew.Sprint(cur.GetValue()) + "<->" + cur = cur.GetNext() + } + + if content[len(content)-3:] == "<->" { + content = content[:len(content)-3] + } + + content += "]" + return content +} + +func (pl *PriorityList) InsertValue(node INode) { + + if pl.head == nil { + pl.head = node + } else { + cur := pl.head + + for cur != nil { + if !cur.Compare(node) { + // 插入该值 + prev := cur.GetPrev() + if prev == nil { + node.SetNext(pl.head) + pl.head = node + } else { + prev.SetNext(node) + node.SetNext(cur) + cur.SetPrev(node) + node.SetPrev(prev) + } + } + cur = cur.GetNext() + } + } +} + +// New 创建 PriorityList +func New() *PriorityList { + return new(PriorityList) +} diff --git a/priority_list_test.go b/priority_list_test.go new file mode 100644 index 0000000..02b0ffb --- /dev/null +++ b/priority_list_test.go @@ -0,0 +1,29 @@ +package crontab + +import "testing" + +type FL struct { + Node +} + +func (fl *FL) Compare(v INode) bool { + return fl.GetValue().(int) > v.GetValue().(int) +} + +func TestPriorityInsert(t *testing.T) { + pl := New() + + fl := new(FL) + fl.SetValue(12) + pl.InsertValue(fl) + fl = new(FL) + fl.SetValue(123) + pl.InsertValue(fl) + fl = new(FL) + fl.SetValue(1233) + pl.InsertValue(fl) + fl = new(FL) + fl.SetValue(1) + pl.InsertValue(fl) + t.Error(pl.String()) +}