status/services/service.go
2025-02-16 11:52:55 +01:00

87 lines
1.6 KiB
Go

package services
import (
"encoding/json"
"fmt"
"sync"
"time"
)
func NewService(msg json.RawMessage) (*Service, error) {
var config struct {
Name string `json:"name"`
Interval int64 `json:"interval"`
Type string `json:"type"`
Config json.RawMessage `json:"config"`
}
err := json.Unmarshal(msg, &config)
if err != nil {
return nil, err
}
interval := time.Duration(config.Interval) * time.Second
factory, found := Factories[config.Type]
if !found {
return nil, fmt.Errorf("no factory: %s", config.Type)
}
check, err := factory(config.Config)
if err != nil {
return nil, fmt.Errorf("failed to create check: %w", err)
}
service := &Service{
Name: config.Name,
Interval: interval,
Check: check,
lastMutex: sync.Mutex{},
lastStatus: StatusUnknown,
lastCheck: time.Unix(0, 0),
}
return service, nil
}
type Service struct {
Name string
Interval time.Duration
Check Check
lastMutex sync.Mutex
lastStatus Status
lastCheck time.Time
}
func (s *Service) Start(stop chan bool) {
ticker := time.Tick(s.Interval)
// Need to do instant check, ticker only sends the first tick after waiting for s.Interval
s.check()
for {
select {
case <-stop:
return
case <-ticker:
s.check()
}
}
}
func (s *Service) check() {
status := s.Check()
s.lastMutex.Lock()
defer s.lastMutex.Unlock()
s.lastStatus = status
s.lastCheck = time.Now().In(time.UTC)
}
func (s *Service) Status() (Status, time.Time) {
s.lastMutex.Lock()
defer s.lastMutex.Unlock()
return s.lastStatus, s.lastCheck
}