birthdaybot/server/worker.go
2023-07-10 19:58:55 +02:00

90 lines
2 KiB
Go

//go:generate mockgen -source=worker.go -destination=mocks/worker_mock.go -package=mocks
package server
import (
"time"
"git.ctrlz.es/mgdelacroix/birthdaybot/model"
"github.com/charmbracelet/log"
)
type Worker interface {
Start()
Stop()
}
type SimpleWorker struct {
server *Server
logger *log.Logger
stop chan bool
stopped chan bool
}
func NewSimpleWorker(server *Server) *SimpleWorker {
return &SimpleWorker{
server: server,
logger: server.Logger,
stop: make(chan bool, 1),
stopped: make(chan bool, 1),
}
}
func (w *SimpleWorker) Start() {
w.logger.Debug("starting worker")
go w.run()
w.logger.Debug("worker started")
}
func (w *SimpleWorker) Stop() {
w.logger.Debug("stopping worker")
w.stop <- true
<-w.stopped
w.logger.Debug("worker stopped")
}
func (w *SimpleWorker) notifyDay(year, month, day int) {
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)
w.server.Notify(b)
}
}
func (w *SimpleWorker) run() {
// 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
w.logger.Debug("first timer tick set", "tick", firstTick)
select {
case <-time.After(firstTick):
ticker = time.NewTicker(24 * time.Hour)
w.notifyDay(eleven.Year(), int(eleven.Month()), eleven.Day())
case <-w.stop:
w.logger.Debug("received stop signal")
w.stopped <- true
return
}
for {
select {
case t := <-ticker.C:
w.logger.Debug("ticker ticked for worker", "tick", t)
w.notifyDay(t.Year(), int(t.Month()), t.Day())
case <-w.stop:
w.logger.Debug("received stop signal")
w.stopped <- true
return
}
}
}