master
兔子 2 years ago
parent 66828b2c23
commit b342ed0dbc

@ -3,6 +3,19 @@ module b612.me/sdk/candy
go 1.20 go 1.20
require ( require (
b612.me/stardb v1.1.3 b612.me/stardb v1.1.4
b612.me/startimer v0.0.0-20230501080256-b0fd8947f0dc b612.me/startimer v0.0.1
github.com/glebarez/go-sqlite v1.21.1
)
require (
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
golang.org/x/sys v0.4.0 // indirect
modernc.org/libc v1.22.3 // indirect
modernc.org/mathutil v1.5.0 // indirect
modernc.org/memory v1.5.0 // indirect
modernc.org/sqlite v1.21.1 // indirect
) )

@ -1,4 +1,27 @@
b612.me/stardb v1.1.3 h1:cx16v64FmfCh+cCF6GDDiVUF+ZISpBxBH3t2GkBkeJY= b612.me/stardb v1.1.4 h1:Ic+CwGZpDKtgHTkDJ5/1kxgEEGM9Hj5xu9i0n6CbXfs=
b612.me/stardb v1.1.3/go.mod h1:qtGEu+joEQxFESl3tse5xqiD767f6sAmHD284+Xoy48= b612.me/stardb v1.1.4/go.mod h1:qtGEu+joEQxFESl3tse5xqiD767f6sAmHD284+Xoy48=
b612.me/startimer v0.0.0-20230501080256-b0fd8947f0dc h1:WO8jZiLVssi3myTWX5Oo/+/i9vk+Alo4ymJhHi4TXp0= b612.me/startimer v0.0.1 h1:7Q4hzkXZR1iFSWyEoTBjUiDx1HsROIvIel3HdfhIhxo=
b612.me/startimer v0.0.0-20230501080256-b0fd8947f0dc/go.mod h1:8fw+OU7SnxzuLkNCYSbRKmvs4WtHs6SbCHuTf5F6s+U= b612.me/startimer v0.0.1/go.mod h1:7YlIWMVBIxLObVI0Ls+CMCCVZJ+4DdTaqF2TshthZjk=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/glebarez/go-sqlite v1.21.1 h1:7MZyUPh2XTrHS7xNEHQbrhfMZuPSzhkm2A1qgg0y5NY=
github.com/glebarez/go-sqlite v1.21.1/go.mod h1:ISs8MF6yk5cL4n/43rSOmVMGJJjHYr7L2MbZZ5Q4E2E=
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
modernc.org/libc v1.22.3 h1:D/g6O5ftAfavceqlLOFwaZuA5KYafKwmr30A6iSqoyY=
modernc.org/libc v1.22.3/go.mod h1:MQrloYP209xa2zHome2a8HLiLm6k0UT8CoHpV74tOFw=
modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ=
modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
modernc.org/memory v1.5.0 h1:N+/8c5rE6EqugZwHii4IFsaJ7MUhoWX07J5tC/iI5Ds=
modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
modernc.org/sqlite v1.21.1 h1:GyDFqNnESLOhwwDRaHGdp2jKLDzpyT/rNLglX3ZkMSU=
modernc.org/sqlite v1.21.1/go.mod h1:XwQ0wZPIh1iKb5mkvCJ3szzbhk+tykC8ZWqTRTgYRwI=

@ -5,18 +5,19 @@ import (
"b612.me/stardb" "b612.me/stardb"
"b612.me/startimer" "b612.me/startimer"
"errors" "errors"
"fmt"
"sync" "sync"
"time" "time"
) )
type Remind struct { type Remind struct {
db *stardb.StarDB db *stardb.StarDB
tasks map[int]RemindTask tasks map[int]Task
mu sync.RWMutex mu sync.RWMutex
callback func(remind RemindTask) callback func(remind Task)
} }
type RemindTask struct { type Task struct {
ID int `db:"id"` ID int `db:"id"`
Origin string `db:"text"` Origin string `db:"text"`
timer *startimer.StarTimer timer *startimer.StarTimer
@ -32,7 +33,7 @@ func getCreateSql() []string {
} }
} }
func NewRemind(db *stardb.StarDB, callback func(task RemindTask)) (*Remind, error) { func NewRemind(db *stardb.StarDB, callback func(task Task)) (*Remind, error) {
if db == nil || db.Db == nil { if db == nil || db.Db == nil {
return nil, errors.New("Invalid hanlder of database") return nil, errors.New("Invalid hanlder of database")
} }
@ -48,13 +49,14 @@ func NewRemind(db *stardb.StarDB, callback func(task RemindTask)) (*Remind, erro
return innerLoadDB(db, callback) return innerLoadDB(db, callback)
} }
func innerLoadDB(db *stardb.StarDB, callback func(task RemindTask)) (*Remind, error) { func innerLoadDB(db *stardb.StarDB, callback func(task Task)) (*Remind, error) {
var rem = Remind{ var rem = Remind{
db: db, db: db,
mu: sync.RWMutex{}, mu: sync.RWMutex{},
callback: callback, callback: callback,
tasks: make(map[int]Task),
} }
var res []RemindTask var res []Task
data, err := db.Query("select * from remind") data, err := db.Query("select * from remind")
if err != nil { if err != nil {
return nil, err return nil, err
@ -64,7 +66,7 @@ func innerLoadDB(db *stardb.StarDB, callback func(task RemindTask)) (*Remind, er
return nil, err return nil, err
} }
if len(res) != 0 { if len(res) != 0 {
rem.tasks = make(map[int]RemindTask, len(res)) rem.tasks = make(map[int]Task, len(res))
for _, task := range res { for _, task := range res {
tmr := startimer.NewTimer(time.Now()) tmr := startimer.NewTimer(time.Now())
err = tmr.ImportRepeats(task.TmrInfo) err = tmr.ImportRepeats(task.TmrInfo)
@ -85,23 +87,28 @@ func innerLoadDB(db *stardb.StarDB, callback func(task RemindTask)) (*Remind, er
return &rem, nil return &rem, nil
} }
func (t RemindTask) GetTimer() startimer.StarTimer { func (t Task) GetTimer() *startimer.StarTimer {
return *t.timer return t.timer
} }
func (r *Remind) callbackFn(task RemindTask) { func (r *Remind) callbackFn(task Task) {
r.callback(task) if r.callback != nil {
r.callback(task)
}
if !task.GetTimer().IsRunning() {
r.DeleteTask(task.ID)
}
} }
func (r *Remind) AddTask(taskStr, key string, msg []byte) (RemindTask, error) { func (r *Remind) AddTask(taskStr, key string, msg []byte) (Task, error) {
tmr, err := when.WhenWithPeriod(taskStr) tmr, err := when.WhenWithPeriod(taskStr)
if err != nil { if err != nil {
return RemindTask{}, err return Task{}, err
} }
exp, err := tmr.ExportRepeats() exp, err := tmr.ExportRepeats()
if err != nil { if err != nil {
return RemindTask{}, err return Task{}, err
} }
var rmt = RemindTask{ var rmt = Task{
Origin: taskStr, Origin: taskStr,
TmrInfo: exp, TmrInfo: exp,
Key: key, Key: key,
@ -113,17 +120,23 @@ func (r *Remind) AddTask(taskStr, key string, msg []byte) (RemindTask, error) {
}) })
res, err := r.db.Insert(rmt, "remind", "id") res, err := r.db.Insert(rmt, "remind", "id")
if err != nil { if err != nil {
return RemindTask{}, err return Task{}, err
} }
id, err := res.LastInsertId() id, err := res.LastInsertId()
if err != nil { if err != nil {
return RemindTask{}, err return Task{}, err
} }
rmt.ID = int(id) rmt.ID = int(id)
r.mu.Lock() r.mu.Lock()
r.tasks[rmt.ID] = rmt r.tasks[rmt.ID] = rmt
r.mu.Unlock() r.mu.Unlock()
rmt.timer.Run() fmt.Println(tmr.ExportRepeats())
err = rmt.timer.Run()
time.Sleep(time.Microsecond * 100)
if err != nil || !rmt.timer.IsRunning() {
r.DeleteTask(rmt.ID)
return Task{}, err
}
return rmt, nil return rmt, nil
} }
@ -147,3 +160,42 @@ func (r *Remind) DeleteTask(id int) error {
delete(r.tasks, id) delete(r.tasks, id)
return nil return nil
} }
func (r *Remind) ListTasks() []Task {
var res = make([]Task, 0, len(r.tasks))
r.mu.RLock()
defer r.mu.RUnlock()
for _, tk := range r.tasks {
res = append(res, tk)
}
return res
}
func (r *Remind) GetTasksByKey(key string) []Task {
var res []Task
r.mu.RLock()
defer r.mu.RUnlock()
for _, tk := range r.tasks {
if tk.Key == key {
res = append(res, tk)
}
}
return res
}
func (r *Remind) Stop() error {
for _, task := range r.tasks {
task.GetTimer().Stop()
}
return nil
}
func (r *Remind) Reset() error {
for _, task := range r.tasks {
err := r.DeleteTask(task.ID)
if err != nil {
return err
}
}
return nil
}

@ -0,0 +1,58 @@
package remind
import (
"b612.me/stardb"
"fmt"
_ "github.com/glebarez/go-sqlite"
"os"
"testing"
"time"
)
func exists(path string) bool {
_, err := os.Stat(path)
if os.IsNotExist(err) {
return false
}
return err == nil
}
func TestRemind(t *testing.T) {
var db stardb.StarDB
err := db.Open("sqlite", "./remind.db")
if err != nil {
t.Fatal(err)
}
sign := make(chan int)
r, err := NewRemind(&db, func(task Task) {
fmt.Println("hello world!", time.Now(), task.ID, task.Key, task.TmrInfo, task.Msg, task.Origin)
sign <- 1
})
if err != nil {
t.Fatal(err)
}
fmt.Println("length of remind", len(r.ListTasks()))
if len(r.ListTasks()) < 2 {
tk, err := r.AddTask("每8秒提醒我吃饭", "干饭", []byte{1, 2, 3})
if err != nil {
t.Fatal(err)
}
tmr := tk.GetTimer()
fmt.Println(tmr.NextTimer())
}
i := 0
for {
select {
case <-sign:
i++
break
case <-time.After(time.Second * 15):
t.FailNow()
}
time.Sleep(time.Second)
fmt.Println(len(r.ListTasks()))
if i == 3 {
break
}
}
}

@ -13,9 +13,10 @@ func matchPeriodPattern01(base time.Time, str string) (startimer.StarTimer, erro
str = transChn(str) str = transChn(str)
var rpt startimer.Repeats var rpt startimer.Repeats
var duration time.Duration var duration time.Duration
reg := regexp.MustCompile(`(每隔|每)?(\d{1,4}年)?(\d{1,5}个?月)?(\d{1,4}[明后大]{0,4}[日号天])?([上中下午夜早凌清晨傍晚里]+)?(\d{1,4}个?[点小时钟:]+)?(\d{1,4}[分:])?(\d{1,10}秒?)?(后)?`) reg := regexp.MustCompile(`(每隔|每)?(\d{0,4}年)?(\d{0,5}个?月)?(\d{0,4}[明后大]{0,4}[日号天])?([上中下午夜早凌清晨傍晚里]+)?(\d{1,4}个?[点小时钟:]+)?(\d{1,4}[分:])?(\d{1,10}秒?)?(后)?`)
if reg.MatchString(str) { if reg.MatchString(str) {
pts := reg.FindStringSubmatch(str) pts := reg.FindStringSubmatch(str)
setAsDate := false
var timeParse = pts[5] var timeParse = pts[5]
count := 1 count := 1
if pts[1] != "" { if pts[1] != "" {
@ -26,19 +27,31 @@ func matchPeriodPattern01(base time.Time, str string) (startimer.StarTimer, erro
if !rpt.Every { if !rpt.Every {
rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_YEAR, Value: uint32(getNumbers(pts[2]))}) rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_YEAR, Value: uint32(getNumbers(pts[2]))})
} else { } else {
duration += time.Hour * 24 * 365 * time.Duration(getNumbers(pts[2])) if getNumbers(pts[2]) == 0 {
setAsDate = true
} else {
duration += time.Hour * 24 * 365 * time.Duration(getNumbers(pts[2]))
}
} }
} }
if pts[3] != "" { if pts[3] != "" {
if !rpt.Every { if !rpt.Every || setAsDate {
rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_MONTH, Value: uint32(getNumbers(pts[3]))}) rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_MONTH, Value: uint32(getNumbers(pts[3]))})
} else { } else {
duration += time.Hour * 24 * 30 * time.Duration(getNumbers(pts[3])) if getNumbers(pts[3]) == 0 {
setAsDate = true
} else {
duration += time.Hour * 24 * 30 * time.Duration(getNumbers(pts[3]))
}
} }
} }
if pts[4] != "" { if pts[4] != "" {
now := time.Now() now := time.Now()
switch pts[4] { switch pts[4] {
case "天":
if rpt.Every {
setAsDate = true
}
case "明天": case "明天":
rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_DAY, Value: uint32(now.Add(time.Hour * 24).Day())}) rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_DAY, Value: uint32(now.Add(time.Hour * 24).Day())})
case "后天": case "后天":
@ -48,27 +61,28 @@ func matchPeriodPattern01(base time.Time, str string) (startimer.StarTimer, erro
case "大大后天": case "大大后天":
rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_DAY, Value: uint32(now.Add(time.Hour * 96).Day())}) rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_DAY, Value: uint32(now.Add(time.Hour * 96).Day())})
default: default:
if !rpt.Every { if setAsDate == rpt.Every {
rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_DAY, Value: uint32(getNumbers(pts[4]))}) rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_DAY, Value: uint32(getNumbers(pts[4]))})
} else { } else {
duration += time.Hour * 24 * time.Duration(getNumbers(pts[4])) duration += time.Hour * 24 * time.Duration(getNumbers(pts[4]))
} }
} }
} }
setAsDate := false
if rpt.Every && timeParse != "" { if rpt.Every && timeParse != "" {
setAsDate = true setAsDate = true
} else if rpt.Every && !strings.Contains(pts[6], "小时") {
setAsDate = true
base = time.Date(base.Year(), base.Month(), base.Day(), 0, 0, 0, 0, base.Location())
} }
//else if rpt.Every && !strings.Contains(pts[6], "小时") {
// setAsDate = true
// base = time.Date(base.Year(), base.Month(), base.Day(), 0, 0, 0, 0, base.Location())
// }
var hour uint32 var hour uint32
if pts[6] != "" { if pts[6] != "" {
hour = uint32(getNumbers(pts[6])) hour = uint32(getNumbers(pts[6]))
if timeParse == "下午" || strings.Contains(timeParse, "晚") || strings.Contains(timeParse, "夜") { if timeParse == "下午" || strings.Contains(timeParse, "晚") || strings.Contains(timeParse, "夜") {
hour += 12 hour += 12
} }
if !setAsDate && !rpt.Every { if rpt.Every == setAsDate {
rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_HOUR, Value: hour}) rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_HOUR, Value: hour})
} else if rpt.Every && !setAsDate { } else if rpt.Every && !setAsDate {
duration += time.Hour * time.Duration(hour) duration += time.Hour * time.Duration(hour)
@ -99,7 +113,7 @@ func matchPeriodPattern01(base time.Time, str string) (startimer.StarTimer, erro
} }
} }
if pts[7] != "" { if pts[7] != "" {
if !setAsDate && !rpt.Every { if rpt.Every == setAsDate {
rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_MINUTE, Value: uint32(getNumbers(pts[7]))}) rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_MINUTE, Value: uint32(getNumbers(pts[7]))})
} else if rpt.Every && !setAsDate { } else if rpt.Every && !setAsDate {
duration += time.Minute * time.Duration(uint32(getNumbers(pts[7]))) duration += time.Minute * time.Duration(uint32(getNumbers(pts[7])))
@ -107,13 +121,13 @@ func matchPeriodPattern01(base time.Time, str string) (startimer.StarTimer, erro
base.Add(time.Minute * time.Duration(uint32(getNumbers(pts[7])))) base.Add(time.Minute * time.Duration(uint32(getNumbers(pts[7]))))
} }
} else if hour != 0 { } else if hour != 0 {
if !rpt.Every && !setAsDate { if rpt.Every == setAsDate {
rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_MINUTE, Value: 0}) rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_MINUTE, Value: 0})
} }
} }
if pts[8] != "" { if pts[8] != "" {
if !setAsDate && !rpt.Every { if rpt.Every == setAsDate {
rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_SECOND, Value: uint32(getNumbers(pts[8]))}) rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_SECOND, Value: uint32(getNumbers(pts[8]))})
} else if rpt.Every && !setAsDate { } else if rpt.Every && !setAsDate {
duration += time.Second * time.Duration(uint32(getNumbers(pts[8]))) duration += time.Second * time.Duration(uint32(getNumbers(pts[8])))
@ -121,7 +135,7 @@ func matchPeriodPattern01(base time.Time, str string) (startimer.StarTimer, erro
base.Add(time.Second * time.Duration(uint32(getNumbers(pts[8])))) base.Add(time.Second * time.Duration(uint32(getNumbers(pts[8]))))
} }
} else if hour != 0 { } else if hour != 0 {
if !rpt.Every && !setAsDate { if rpt.Every == setAsDate {
rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_SECOND, Value: 0}) rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_SECOND, Value: 0})
} }
} }
@ -151,6 +165,9 @@ func matchPeriodPattern01(base time.Time, str string) (startimer.StarTimer, erro
if duration.Seconds() > 0 { if duration.Seconds() > 0 {
rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_SECOND, Value: uint32(duration.Seconds())}) rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_SECOND, Value: uint32(duration.Seconds())})
} }
if rpt.Every == setAsDate {
rpt.Every = false
}
return startimer.NewTimer(base, startimer.WithRepeats(&rpt), startimer.WithRunCountLimit(count)), nil return startimer.NewTimer(base, startimer.WithRepeats(&rpt), startimer.WithRunCountLimit(count)), nil
} }
return startimer.StarTimer{}, errors.New("no Match") return startimer.StarTimer{}, errors.New("no Match")
@ -182,6 +199,9 @@ func matchPeroidPattern02(base time.Time, str string) (startimer.StarTimer, erro
} }
rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_WEEK, Value: uint32(num)}) rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_WEEK, Value: uint32(num)})
} }
} else {
wkNum := getNumbers(wk)
rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_WEEK, Value: uint32(wkNum)})
} }
} }

@ -8,8 +8,17 @@ import (
func TestParse(t *testing.T) { func TestParse(t *testing.T) {
for _, code := range []string{"一个小时后告诉我事情", "三个小时后爱我", "每两个小时提醒我吃饭", for _, code := range []string{"一个小时后告诉我事情", "三个小时后爱我", "每两个小时提醒我吃饭",
"每五个月零二十五天三小时25分15秒告诉我时间", "5月23日上午3点24分12秒打我", "周四上午11点提醒我", "每五个月零二十五天三小时25分15秒告诉我时间", "5月23日上午3点24分12秒打我", "周五上午11点提醒我", "5时25分提醒我",
"每周一到周五上午8点提醒我吃饭"} { "每周一到周五上午8点提醒我吃饭", "每天晚上8点提醒我吃饭", "每月16号晚上8点提醒我吃饭"} {
a, _ := WhenWithPeriod(code)
//fmt.Println(a.Repeats()[0])
fmt.Println(a.NextTimer(), a.RunCountLimit(), code)
fmt.Println(a.NextTimerAfterDate(time.Now().Add(time.Hour * 72)))
}
}
func TestSigParse(t *testing.T) {
for _, code := range []string{"每月16号晚上8点提醒我吃饭"} {
a, _ := WhenWithPeriod(code) a, _ := WhenWithPeriod(code)
//fmt.Println(a.Repeats()[0]) //fmt.Println(a.Repeats()[0])
fmt.Println(a.NextTimer(), a.RunCountLimit(), code) fmt.Println(a.NextTimer(), a.RunCountLimit(), code)

Loading…
Cancel
Save