feat: publish standalone worker
Separate worker packaging and service lifecycle from the control plane.
Этот коммит содержится в:
117
internal/notifier/run_exp.go
Обычный файл
117
internal/notifier/run_exp.go
Обычный файл
@@ -0,0 +1,117 @@
|
||||
package notifier
|
||||
|
||||
import (
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"rsgit.ru/rsmon/rsmon/app/models"
|
||||
)
|
||||
|
||||
// RunExp provides functionality.
|
||||
//
|
||||
// A panic in any single check's notification must not kill the scheduler
|
||||
// goroutine. The defensive recover() keeps the 2h tick alive even if
|
||||
// RunExpCheck trips over a bad row or a stale schema reference.
|
||||
func RunExp() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
log.Printf("notifier: RunExp recovered from panic: %v", r)
|
||||
}
|
||||
}()
|
||||
|
||||
_ = models.LogCheck("exp")
|
||||
|
||||
checks := make([]models.Check, 0)
|
||||
|
||||
err := models.ExpScope(models.DB()).Find(&checks).Error
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
for i := range checks {
|
||||
RunExpCheck(&checks[i])
|
||||
}
|
||||
}
|
||||
|
||||
// RunExpCheck provides functionality.
|
||||
//
|
||||
// A panic in any per-row work (notifier, contact lookup, message write) is
|
||||
// contained here so one bad row cannot take down the whole RunExp scheduler.
|
||||
// The panic is logged with the check id and the loop continues.
|
||||
func RunExpCheck(c *models.Check) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
log.Printf("notifier: RunExpCheck recovered from panic on check %d: %v", c.ID, r)
|
||||
}
|
||||
}()
|
||||
|
||||
if c.Monitor == nil {
|
||||
log.Println("!BUG! check", c.ID, "has no Monitor (or not preloaded). Monitor ID: ", c.MonitorID, " Not running.")
|
||||
log.Println()
|
||||
return
|
||||
}
|
||||
if !c.Monitor.Enabled {
|
||||
return
|
||||
}
|
||||
|
||||
if c.Monitor.Group == nil {
|
||||
log.Println("!BUG! check", c.ID, "has no Monitor (or not preloaded). Monitor ID: ", c.Monitor.ID, ", group id:", c.Monitor.GroupID, " Not running.") //nolint:lll
|
||||
return
|
||||
}
|
||||
if c.Monitor.Group.Notifications == nil {
|
||||
log.Println("!BUG! check", c.ID, "has no .Monitor.Group.Notifications (or not preloaded). Not running.")
|
||||
return
|
||||
}
|
||||
|
||||
for i := range c.Monitor.Group.Notifications {
|
||||
n := &c.Monitor.Group.Notifications[i]
|
||||
if n.BeforeExpiration == nil {
|
||||
continue
|
||||
}
|
||||
if c.Expires == nil {
|
||||
// should not happen
|
||||
continue
|
||||
}
|
||||
if c.Kind == "whois" && !n.NotifyWHOIS {
|
||||
continue
|
||||
}
|
||||
if c.Kind == "ssl" && !n.NotifySSL {
|
||||
continue
|
||||
}
|
||||
|
||||
// notify delay not reached
|
||||
notifyOn := time.Now().Add(time.Second * time.Duration(*n.BeforeExpiration))
|
||||
if c.Expires.After(notifyOn) {
|
||||
continue
|
||||
}
|
||||
|
||||
createExpMessage(c, n)
|
||||
}
|
||||
}
|
||||
|
||||
func createExpMessage(c *models.Check, n *models.Notification) {
|
||||
for _, contact := range n.GetContacts() { //nolint:gocritic // range copy is acceptable here
|
||||
message := models.Message{
|
||||
CheckID: &c.ID,
|
||||
NotificationID: n.ID,
|
||||
ContactID: contact.ID,
|
||||
Kind: "exp",
|
||||
}
|
||||
|
||||
models.DB().
|
||||
Where(message).
|
||||
Where("created_at > ?", time.Now().Add(-time.Hour*24*14)).
|
||||
Find(&message)
|
||||
if message.ID > 0 {
|
||||
continue
|
||||
}
|
||||
message.State = models.TaskStateQueued
|
||||
err := models.DB().Save(&message).Error
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
// panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
Ссылка в новой задаче
Block a user