-
Notifications
You must be signed in to change notification settings - Fork 223
/
server.go
120 lines (100 loc) 路 2 KB
/
server.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package crontab
import (
"context"
"fmt"
"log"
"time"
"github.com/pkg/errors"
"github.com/robfig/cron/v3"
"github.com/go-eagle/eagle/pkg/config"
)
// Config crontab config
type Config struct {
Timezone string
Tasks []Task
}
// Task crontab task
type Task struct {
Name string
Schedule string
}
// Server crontab server
type Server struct {
conf *Config
// cron schedule
schedule *cron.Cron
jobs map[string]cron.Job
logger cron.Logger
stop chan struct{}
}
// NewServer new a crontab server
func NewServer(jobs map[string]cron.Job, logger cron.Logger) *Server {
// load config
cfg, err := loadConf()
if err != nil {
panic(err)
}
if len(cfg.Tasks) == 0 {
panic("crontab config is empty")
}
if len(jobs) == 0 || jobs == nil {
panic("crontab jobs is empty")
}
if len(cfg.Tasks) != len(jobs) {
panic("crontab tasks and jobs not match")
}
loc, err := time.LoadLocation(cfg.Timezone)
if err != nil {
panic(err)
}
// new server
return &Server{
conf: cfg,
schedule: cron.New(
cron.WithLocation(loc),
cron.WithLogger(logger),
),
jobs: jobs,
stop: make(chan struct{}, 1),
}
}
// Start the crontab server
func (s *Server) Start(ctx context.Context) error {
for _, task := range s.conf.Tasks {
task := task
// get job
job, ok := s.jobs[task.Name]
if !ok {
return fmt.Errorf("[crontab] job not found: %s", task.Name)
}
_, err := s.schedule.AddJob(task.Schedule, job)
if err != nil {
return errors.Wrapf(err, "[crontab] add job [%s] error", task.Name)
}
}
s.schedule.Start()
select {
case <-s.stop:
s.schedule.Stop()
}
return nil
}
// Stop the crontab server
func (s *Server) Stop(ctx context.Context) error {
log.Printf("[crontab] server stopping...")
s.stop <- struct{}{}
return nil
}
// loadConf load config
func loadConf() (ret *Config, err error) {
v, err := config.LoadWithType("crontab", "yaml")
if err != nil {
return nil, err
}
c := Config{}
err = v.Unmarshal(&c)
if err != nil {
return nil, err
}
return &c, nil
}