agent/update/timed.go (54 lines of code) (raw):
package update
import (
"errors"
"sync"
"time"
"github.com/aliyun/aliyun_assist_client/agent/log"
"github.com/aliyun/aliyun_assist_client/agent/taskengine/timermanager"
)
const (
// DefaultCheckIntervalSeconds is the default interval for update check timer
DefaultCheckIntervalSeconds = 1800
)
var (
// TODO: Centralized manager for timers of essential tasks
_checkTimer *timermanager.Timer
// TODO: Centralized manager for timers of essential tasks, then get rid of this
_checkTimerInitLock sync.Mutex
)
func doCheck() {
// Periodic checking update uses loose timeout limitation
if err := SafeUpdate(time.Duration(60) * time.Second, time.Duration(30) * time.Second, UpdateReasonPeriod); err != nil {
log.GetLogger().WithError(err).Errorln("Failed to check update periodically")
}
}
func InitCheckUpdateTimer() error {
if _checkTimer == nil {
_checkTimerInitLock.Lock()
defer _checkTimerInitLock.Unlock()
if _checkTimer == nil {
timerManager := timermanager.GetTimerManager()
timer, err := timerManager.CreateTimerInSeconds(doCheck, DefaultCheckIntervalSeconds)
if err != nil {
return err
}
_checkTimer = timer
// Checking update at starting SHOULD be executed in main goroutine,
// subsequent checking would be invoked in TimerManager goroutines
mutableSchedule, ok := _checkTimer.Schedule.(*timermanager.MutableScheduled)
if !ok {
return errors.New("Unexpected schedule type of netstat timer")
}
mutableSchedule.NotImmediately()
_, err = _checkTimer.Run()
if err != nil {
return err
}
return nil
}
return errors.New("Update check timer has been initialized")
}
return errors.New("Update check timer has been initialized")
}
// TriggerUpgrade triggers doCheck() by call timer.SkipWaiting()
func TriggerUpdateCheck() {
_checkTimerInitLock.Lock()
defer _checkTimerInitLock.Unlock()
if _checkTimer == nil {
return
}
_checkTimer.SkipWaiting()
}