88 lines
1.6 KiB
Go
88 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
|
||
|
}
|