mihomo/ntp/service.go

96 lines
1.8 KiB
Go
Raw Normal View History

2023-09-01 03:11:35 +08:00
package ntp
import (
"context"
"github.com/Dreamacro/clash/log"
"github.com/beevik/ntp"
"sync"
"time"
)
var offset time.Duration
var service *Service
type Service struct {
addr string
interval time.Duration
ticker *time.Ticker
ctx context.Context
cancel context.CancelFunc
2023-09-02 12:37:43 +08:00
mu sync.Mutex
2023-09-01 03:11:35 +08:00
running bool
}
func ReCreateNTPService(addr string, interval time.Duration) {
if service != nil {
service.Stop()
}
ctx, cancel := context.WithCancel(context.Background())
2023-09-02 12:37:43 +08:00
service = &Service{addr: addr, interval: interval, ctx: ctx, cancel: cancel}
2023-09-01 03:11:35 +08:00
service.Start()
}
func (srv *Service) Start() {
srv.mu.Lock()
defer srv.mu.Unlock()
log.Infoln("NTP service start")
srv.ticker = time.NewTicker(srv.interval * time.Minute)
service.running = true
go func() {
for {
err := srv.updateTime(srv.addr)
if err != nil {
2023-09-02 12:37:43 +08:00
log.Warnln("updateTime failed: %s", err)
2023-09-01 03:11:35 +08:00
}
select {
case <-srv.ticker.C:
case <-srv.ctx.Done():
return
}
}
}()
}
func (srv *Service) Stop() {
srv.mu.Lock()
defer srv.mu.Unlock()
2023-09-02 12:37:43 +08:00
if service.running {
srv.ticker.Stop()
srv.cancel()
service.running = false
}
}
func (srv *Service) Running() bool {
if srv == nil {
return false
}
srv.mu.Lock()
defer srv.mu.Unlock()
return srv.running
2023-09-01 03:11:35 +08:00
}
func (srv *Service) updateTime(addr string) error {
response, err := ntp.Query(addr)
if err != nil {
return err
}
localTime := time.Now()
ntpTime := response.Time
offset = localTime.Sub(ntpTime)
if offset > time.Duration(0) {
2023-09-02 12:37:43 +08:00
log.Warnln("System clock is ahead of NTP time by %s", offset)
2023-09-01 03:11:35 +08:00
} else if offset < time.Duration(0) {
2023-09-02 12:37:43 +08:00
log.Warnln("System clock is behind NTP time by %s", -offset)
2023-09-01 03:11:35 +08:00
}
return nil
}
func Now() time.Time {
now := time.Now()
2023-09-02 12:37:43 +08:00
if service.Running() && offset.Abs() > 0 {
2023-09-01 03:11:35 +08:00
now = now.Add(offset)
}
return now
}