This commit is contained in:
2023-05-17 17:11:06 +08:00
parent 66828b2c23
commit b342ed0dbc
6 changed files with 215 additions and 40 deletions
+70 -18
View File
@@ -5,18 +5,19 @@ import (
"b612.me/stardb"
"b612.me/startimer"
"errors"
"fmt"
"sync"
"time"
)
type Remind struct {
db *stardb.StarDB
tasks map[int]RemindTask
tasks map[int]Task
mu sync.RWMutex
callback func(remind RemindTask)
callback func(remind Task)
}
type RemindTask struct {
type Task struct {
ID int `db:"id"`
Origin string `db:"text"`
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 {
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)
}
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{
db: db,
mu: sync.RWMutex{},
callback: callback,
tasks: make(map[int]Task),
}
var res []RemindTask
var res []Task
data, err := db.Query("select * from remind")
if err != nil {
return nil, err
@@ -64,7 +66,7 @@ func innerLoadDB(db *stardb.StarDB, callback func(task RemindTask)) (*Remind, er
return nil, err
}
if len(res) != 0 {
rem.tasks = make(map[int]RemindTask, len(res))
rem.tasks = make(map[int]Task, len(res))
for _, task := range res {
tmr := startimer.NewTimer(time.Now())
err = tmr.ImportRepeats(task.TmrInfo)
@@ -85,23 +87,28 @@ func innerLoadDB(db *stardb.StarDB, callback func(task RemindTask)) (*Remind, er
return &rem, nil
}
func (t RemindTask) GetTimer() startimer.StarTimer {
return *t.timer
func (t Task) GetTimer() *startimer.StarTimer {
return t.timer
}
func (r *Remind) callbackFn(task RemindTask) {
r.callback(task)
func (r *Remind) callbackFn(task 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)
if err != nil {
return RemindTask{}, err
return Task{}, err
}
exp, err := tmr.ExportRepeats()
if err != nil {
return RemindTask{}, err
return Task{}, err
}
var rmt = RemindTask{
var rmt = Task{
Origin: taskStr,
TmrInfo: exp,
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")
if err != nil {
return RemindTask{}, err
return Task{}, err
}
id, err := res.LastInsertId()
if err != nil {
return RemindTask{}, err
return Task{}, err
}
rmt.ID = int(id)
r.mu.Lock()
r.tasks[rmt.ID] = rmt
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
}
@@ -147,3 +160,42 @@ func (r *Remind) DeleteTask(id int) error {
delete(r.tasks, id)
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
}
+58
View File
@@ -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
}
}
}