58 lines
1.1 KiB
Go
58 lines
1.1 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"log/slog"
|
|
"time"
|
|
)
|
|
|
|
// 定时任务实现
|
|
type scheduledTask struct {
|
|
fn func()
|
|
interval time.Duration
|
|
cancel context.CancelFunc
|
|
done chan struct{} // 服务协程退出信号
|
|
}
|
|
|
|
// Stop implements QcDataHandleScheduleTask.
|
|
func (t *scheduledTask) Stop() {
|
|
t.cancel()
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
|
|
defer cancel()
|
|
select {
|
|
case <-t.done:
|
|
slog.Info("定时任务线程退出")
|
|
case <-ctx.Done():
|
|
slog.Warn("定时任务线程超时退出")
|
|
}
|
|
}
|
|
|
|
func (t *scheduledTask) run(ctx context.Context) {
|
|
defer close(t.done)
|
|
mainLoop:
|
|
for {
|
|
select {
|
|
case <-ctx.Done():
|
|
break mainLoop
|
|
default:
|
|
}
|
|
t.fn()
|
|
time.Sleep(t.interval)
|
|
}
|
|
}
|
|
|
|
func NewScheduledTask(run func(), interval time.Duration) IScheduledTask {
|
|
if interval <= 0 {
|
|
interval = time.Second
|
|
}
|
|
task := &scheduledTask{
|
|
fn: run,
|
|
interval: interval,
|
|
done: make(chan struct{}),
|
|
}
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
go task.run(ctx)
|
|
task.cancel = cancel
|
|
return task
|
|
}
|