donetick/internal/notifier/scheduler.go

104 lines
3 KiB
Go
Raw Normal View History

2024-06-30 21:41:41 -04:00
package notifier
import (
"context"
"log"
"time"
"donetick.com/core/config"
chRepo "donetick.com/core/internal/chore/repo"
nRepo "donetick.com/core/internal/notifier/repo"
uRepo "donetick.com/core/internal/user/repo"
"donetick.com/core/logging"
)
type keyType string
const (
SchedulerKey keyType = "scheduler"
)
type Scheduler struct {
choreRepo *chRepo.ChoreRepository
userRepo *uRepo.UserRepository
stopChan chan bool
notifier *Notifier
2024-06-30 21:41:41 -04:00
notificationRepo *nRepo.NotificationRepository
SchedulerJobs config.SchedulerConfig
}
func NewScheduler(cfg *config.Config, ur *uRepo.UserRepository, cr *chRepo.ChoreRepository, n *Notifier, nr *nRepo.NotificationRepository) *Scheduler {
2024-06-30 21:41:41 -04:00
return &Scheduler{
choreRepo: cr,
userRepo: ur,
stopChan: make(chan bool),
notifier: n,
notificationRepo: nr,
SchedulerJobs: cfg.SchedulerJobs,
}
}
func (s *Scheduler) Start(c context.Context) {
log := logging.FromContext(c)
log.Debug("Scheduler started")
go s.runScheduler(c, " NOTIFICATION_SCHEDULER ", s.loadAndSendNotificationJob, 3*time.Minute)
go s.runScheduler(c, " NOTIFICATION_CLEANUP ", s.cleanupSentNotifications, 24*time.Hour*30)
}
func (s *Scheduler) cleanupSentNotifications(c context.Context) (time.Duration, error) {
log := logging.FromContext(c)
deleteBefore := time.Now().UTC().Add(-time.Hour * 24 * 30)
err := s.notificationRepo.DeleteSentNotifications(c, deleteBefore)
if err != nil {
log.Error("Error deleting sent notifications", err)
return time.Duration(0), err
}
return time.Duration(0), nil
2024-06-30 21:41:41 -04:00
}
func (s *Scheduler) loadAndSendNotificationJob(c context.Context) (time.Duration, error) {
log := logging.FromContext(c)
startTime := time.Now()
getAllPendingNotifications, err := s.notificationRepo.GetPendingNotificaiton(c, time.Minute*900)
2024-06-30 21:41:41 -04:00
log.Debug("Getting pending notifications", " count ", len(getAllPendingNotifications))
if err != nil {
log.Error("Error getting pending notifications")
return time.Since(startTime), err
}
for _, notification := range getAllPendingNotifications {
err := s.notifier.SendNotification(c, notification)
if err != nil {
log.Error("Error sending notification", err)
continue
}
2024-06-30 21:41:41 -04:00
notification.IsSent = true
}
s.notificationRepo.MarkNotificationsAsSent(getAllPendingNotifications)
return time.Since(startTime), nil
}
func (s *Scheduler) runScheduler(c context.Context, jobName string, job func(c context.Context) (time.Duration, error), interval time.Duration) {
for {
logging.FromContext(c).Debug("Scheduler running ", jobName, " time", time.Now().String())
select {
case <-s.stopChan:
log.Println("Scheduler stopped")
return
default:
elapsedTime, err := job(c)
if err != nil {
logging.FromContext(c).Error("Error running scheduler job", err)
}
logging.FromContext(c).Debug("Scheduler job completed", jobName, " time: ", elapsedTime.String())
2024-06-30 21:41:41 -04:00
}
time.Sleep(interval)
}
}
func (s *Scheduler) Stop() {
s.stopChan <- true
}