2023-07-10 12:43:59 +01:00
|
|
|
//go:generate mockgen -source=worker.go -destination=mocks/worker_mock.go -package=mocks
|
2023-07-01 16:23:19 +01:00
|
|
|
package server
|
|
|
|
|
|
|
|
import (
|
|
|
|
"time"
|
|
|
|
|
2023-07-10 09:16:36 +01:00
|
|
|
"git.ctrlz.es/mgdelacroix/birthdaybot/model"
|
2023-07-01 16:23:19 +01:00
|
|
|
"github.com/charmbracelet/log"
|
|
|
|
)
|
|
|
|
|
2023-07-10 12:39:25 +01:00
|
|
|
type Worker interface {
|
|
|
|
Start()
|
|
|
|
Stop()
|
|
|
|
}
|
|
|
|
|
|
|
|
type SimpleWorker struct {
|
2023-07-04 11:29:13 +01:00
|
|
|
server *Server
|
2023-07-01 16:23:19 +01:00
|
|
|
logger *log.Logger
|
|
|
|
stop chan bool
|
|
|
|
stopped chan bool
|
|
|
|
}
|
|
|
|
|
2023-07-10 12:39:25 +01:00
|
|
|
func NewSimpleWorker(server *Server) *SimpleWorker {
|
|
|
|
return &SimpleWorker{
|
2023-07-04 11:29:13 +01:00
|
|
|
server: server,
|
|
|
|
logger: server.Logger,
|
2023-07-01 16:23:19 +01:00
|
|
|
stop: make(chan bool, 1),
|
|
|
|
stopped: make(chan bool, 1),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-10 12:39:25 +01:00
|
|
|
func (w *SimpleWorker) Start() {
|
2023-07-10 18:58:55 +01:00
|
|
|
w.logger.Debug("starting worker")
|
2023-07-01 16:23:19 +01:00
|
|
|
go w.run()
|
2023-07-10 18:58:55 +01:00
|
|
|
w.logger.Debug("worker started")
|
2023-07-01 16:23:19 +01:00
|
|
|
}
|
|
|
|
|
2023-07-10 12:39:25 +01:00
|
|
|
func (w *SimpleWorker) Stop() {
|
2023-07-10 18:58:55 +01:00
|
|
|
w.logger.Debug("stopping worker")
|
2023-07-01 16:23:19 +01:00
|
|
|
w.stop <- true
|
|
|
|
<-w.stopped
|
2023-07-10 18:58:55 +01:00
|
|
|
w.logger.Debug("worker stopped")
|
2023-07-01 16:23:19 +01:00
|
|
|
}
|
|
|
|
|
2023-07-10 12:39:25 +01:00
|
|
|
func (w *SimpleWorker) notifyDay(year, month, day int) {
|
2023-07-10 09:16:36 +01:00
|
|
|
birthdays := model.FilterByDate(w.server.Birthdays(), year, month, day)
|
|
|
|
w.logger.Info("notifying for date", "birthdays", len(birthdays), "year", year, "month", month, "day", day)
|
|
|
|
|
|
|
|
for _, b := range birthdays {
|
|
|
|
w.logger.Info("notifying for birthday", "name", b.Name)
|
2023-07-11 15:43:20 +01:00
|
|
|
if err := w.server.Notify(b); err != nil {
|
|
|
|
w.logger.Error("error notifying for birthday", "name", b.Name, "error", err)
|
|
|
|
}
|
2023-07-10 09:16:36 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-10 12:39:25 +01:00
|
|
|
func (w *SimpleWorker) run() {
|
2023-07-10 09:16:36 +01:00
|
|
|
// first we calculate the delta with 23:00
|
|
|
|
now := time.Now()
|
|
|
|
eleven := time.Date(now.Year(), now.Month(), now.Day(), 23, 0, 0, 0, now.Location())
|
|
|
|
|
|
|
|
if eleven.Before(now) {
|
|
|
|
// tomorrow at 23:00
|
|
|
|
eleven = time.Date(now.Year(), now.Month(), now.Day()+1, 23, 0, 0, 0, now.Location())
|
|
|
|
}
|
|
|
|
|
|
|
|
firstTick := eleven.Sub(now)
|
|
|
|
|
|
|
|
var ticker *time.Ticker
|
2023-07-10 18:58:55 +01:00
|
|
|
w.logger.Debug("first timer tick set", "tick", firstTick)
|
2023-07-10 09:16:36 +01:00
|
|
|
select {
|
|
|
|
case <-time.After(firstTick):
|
|
|
|
ticker = time.NewTicker(24 * time.Hour)
|
|
|
|
w.notifyDay(eleven.Year(), int(eleven.Month()), eleven.Day())
|
|
|
|
case <-w.stop:
|
2023-07-10 18:58:55 +01:00
|
|
|
w.logger.Debug("received stop signal")
|
2023-07-10 09:16:36 +01:00
|
|
|
w.stopped <- true
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2023-07-01 16:23:19 +01:00
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case t := <-ticker.C:
|
2023-07-10 18:58:55 +01:00
|
|
|
w.logger.Debug("ticker ticked for worker", "tick", t)
|
2023-07-10 09:16:36 +01:00
|
|
|
w.notifyDay(t.Year(), int(t.Month()), t.Day())
|
2023-07-01 16:23:19 +01:00
|
|
|
case <-w.stop:
|
2023-07-10 18:58:55 +01:00
|
|
|
w.logger.Debug("received stop signal")
|
2023-07-01 16:23:19 +01:00
|
|
|
w.stopped <- true
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|