Skip to content

Commit a7b76b5

Browse files
pillar/updateTaskTimer: switch to less-error prone
time.Duration Signed-off-by: Christoph Ostarek <[email protected]>
1 parent 726e691 commit a7b76b5

File tree

6 files changed

+99
-35
lines changed

6 files changed

+99
-35
lines changed

pkg/pillar/cmd/zedagent/handlecertconfig.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -200,13 +200,13 @@ func controllerCertsTask(ctx *zedagentContext, triggerCerts <-chan struct{}) {
200200
// Run a timer for extra safety to handle controller certificates updates
201201
// If we failed with the initial we have a short timer, otherwise
202202
// the configurable one.
203-
const shortTime = 120 // Two minutes
204-
certInterval := ctx.globalConfig.GlobalValueInt(types.CertInterval)
203+
const shortTime = 2 * time.Minute
204+
certInterval := ctx.globalConfig.GlobalValueDuration(types.CertInterval)
205205
if retry {
206206
log.Noticef("Initial getCertsFromController failed; switching to short timer")
207207
certInterval = shortTime
208208
}
209-
interval := time.Duration(certInterval) * time.Second
209+
interval := certInterval
210210
max := float64(interval)
211211
min := max * 0.3
212212
periodicTicker := flextimer.NewRangeTicker(time.Duration(min),
@@ -232,14 +232,13 @@ func controllerCertsTask(ctx *zedagentContext, triggerCerts <-chan struct{}) {
232232
ctx.ps.StillRunning(wdName, warningTime, errorTime)
233233
if retry && success {
234234
log.Noticef("getCertsFromController succeeded; switching to long timer %d seconds",
235-
ctx.globalConfig.GlobalValueInt(types.CertInterval))
236-
updateTaskTimer(ctx.globalConfig.GlobalValueInt(types.CertInterval),
235+
ctx.globalConfig.GlobalValueDuration(types.CertInterval))
236+
updateTaskTimer(ctx.globalConfig.GlobalValueDuration(types.CertInterval),
237237
ctx.getconfigCtx.certTickerHandle)
238238
retry = false
239239
} else if !retry && !success {
240240
log.Noticef("getCertsFromController failed; switching to short timer")
241-
updateTaskTimer(shortTime,
242-
ctx.getconfigCtx.certTickerHandle)
241+
updateTaskTimer(shortTime, ctx.getconfigCtx.certTickerHandle)
243242
retry = true
244243
}
245244
}

pkg/pillar/cmd/zedagent/handleconfig.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -516,16 +516,15 @@ func updateConfigTimer(configInterval uint32, tickerHandle interface{}) {
516516

517517
// updateTaskTimer updates the given tickerHandle to use a new interval based on configInterval.
518518
// It adjusts the ticker's range and triggers an immediate tick to ensure the new interval takes effect promptly.
519-
func updateTaskTimer(configInterval uint32, tickerHandle interface{}) {
519+
func updateTaskTimer(configInterval time.Duration, tickerHandle interface{}) {
520520

521521
if tickerHandle == nil {
522522
// Happens if the tickerHandle has not been initialized yet.
523523
log.Warnf("updateConfigTimer: no tickerHandle yet")
524524
return
525525
}
526-
interval := time.Duration(configInterval) * time.Second
527-
log.Functionf("updateTaskTimer() change to %v", interval)
528-
max := float64(interval)
526+
log.Functionf("updateTaskTimer() change to %v", configInterval)
527+
max := float64(configInterval)
529528
min := max * 0.3
530529
// Update the ticker to use the new interval range.
531530
flextimer.UpdateRangeTicker(tickerHandle,

pkg/pillar/cmd/zedagent/handlemetrics.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,16 +1013,16 @@ func hardwareHealthTimerTask(ctx *zedagentContext, handleChannel chan interface{
10131013
// Run a timer for extra safety to send hardwarehealth updates
10141014
// If we failed with the initial we have a short timer, otherwise
10151015
// the configurable one.
1016-
const shortTimeSecs = 120 // Short time: two minutes
1017-
hardwareHealthInterval := ctx.globalConfig.GlobalValueInt(types.HardwareHealthInterval)
1018-
interval := time.Duration(hardwareHealthInterval)
1016+
const shortTime = 2 * time.Minute
1017+
hardwareHealthInterval := ctx.globalConfig.GlobalValueDuration(types.HardwareHealthInterval)
1018+
interval := hardwareHealthInterval
10191019
if retry {
10201020
log.Noticef("Initial publishHardwareHealth failed; switching to short timer")
1021-
interval = shortTimeSecs
1021+
interval = shortTime
10221022
}
1023-
max := float64(interval * time.Second)
1024-
min := max * 0.3
1025-
ticker := flextimer.NewRangeTicker(time.Duration(min), time.Duration(max))
1023+
max := interval
1024+
min := time.Duration(max.Seconds() * 0.3 * float64(time.Second))
1025+
ticker := flextimer.NewRangeTicker(min, max)
10261026
// Return handle to caller
10271027
handleChannel <- ticker
10281028

@@ -1049,7 +1049,7 @@ func hardwareHealthTimerTask(ctx *zedagentContext, handleChannel chan interface{
10491049
retry = false
10501050
} else if !retry && !success {
10511051
log.Noticef("Hardwarehealth failed; switching to short timer")
1052-
updateTaskTimer(shortTimeSecs, ticker)
1052+
updateTaskTimer(shortTime, ticker)
10531053
retry = true
10541054
}
10551055
case <-stillRunning.C:

pkg/pillar/cmd/zedagent/parseconfig.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2854,8 +2854,8 @@ func parseConfigItems(ctx *getconfigContext, config *zconfig.EdgeDevConfig,
28542854
// Set GlobalStatus Values from GlobalConfig.
28552855
oldConfigInterval := oldGlobalConfig.GlobalValueInt(types.ConfigInterval)
28562856
newConfigInterval := newGlobalConfig.GlobalValueInt(types.ConfigInterval)
2857-
oldCertInterval := oldGlobalConfig.GlobalValueInt(types.CertInterval)
2858-
newCertInterval := newGlobalConfig.GlobalValueInt(types.CertInterval)
2857+
oldCertInterval := oldGlobalConfig.GlobalValueDuration(types.CertInterval)
2858+
newCertInterval := newGlobalConfig.GlobalValueDuration(types.CertInterval)
28592859

28602860
oldMetricInterval := oldGlobalConfig.GlobalValueInt(types.MetricInterval)
28612861
newMetricInterval := newGlobalConfig.GlobalValueInt(types.MetricInterval)

pkg/pillar/types/global.go

Lines changed: 78 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"regexp"
1010
"strconv"
1111
"strings"
12+
"time"
1213

1314
"github.com/sirupsen/logrus" // OK for logrus.Fatal
1415
)
@@ -34,6 +35,9 @@ const (
3435
SenderStatusDebug // Not a failure
3536
)
3637

38+
// see also https://brandur.org/fragments/go-max-time-duration
39+
const maxDuration time.Duration = 1<<63 - 1
40+
3741
// String prints ASCII
3842
func (status SenderStatus) String() string {
3943
switch status {
@@ -434,6 +438,8 @@ const (
434438
ConfigItemTypeString
435439
// ConfigItemTypeTriState - for config item's who's value is a tristate
436440
ConfigItemTypeTriState
441+
// ConfigItemTypeDuration - for config item's who's value is a duration
442+
ConfigItemTypeDuration
437443
)
438444

439445
var (
@@ -485,6 +491,10 @@ type ConfigItemSpec struct {
485491
IntMax uint32
486492
IntDefault uint32
487493

494+
DurationMin time.Duration
495+
DurationMax time.Duration
496+
DurationDefault time.Duration
497+
488498
StringValidator Validator
489499
StringDefault string
490500
BoolDefault bool
@@ -505,6 +515,8 @@ func (configSpec ConfigItemSpec) DefaultValue() ConfigItemValue {
505515
item.StrValue = configSpec.StringDefault
506516
case ConfigItemTypeTriState:
507517
item.TriStateValue = configSpec.TriStateDefault
518+
case ConfigItemTypeDuration:
519+
item.DurationValue = configSpec.DurationDefault
508520
}
509521
return item
510522
}
@@ -520,6 +532,24 @@ type ConfigItemSpecMap struct {
520532
AgentSettings map[AgentSettingKey]ConfigItemSpec
521533
}
522534

535+
// AddDurationItem - Adds integer item to specMap
536+
func (specMap *ConfigItemSpecMap) AddDurationItem(key GlobalSettingKey,
537+
defaultDuration, minDuration, maxDuration time.Duration) {
538+
539+
if defaultDuration < minDuration || defaultDuration > maxDuration {
540+
logrus.Fatalf("Adding int item %s failed. Value does not meet given min/max criteria", key)
541+
}
542+
543+
configItem := ConfigItemSpec{
544+
ItemType: ConfigItemTypeDuration,
545+
Key: string(key),
546+
DurationDefault: defaultDuration,
547+
DurationMin: minDuration,
548+
DurationMax: maxDuration,
549+
}
550+
specMap.GlobalSettings[key] = configItem
551+
}
552+
523553
// AddIntItem - Adds integer item to specMap
524554
func (specMap *ConfigItemSpecMap) AddIntItem(key GlobalSettingKey,
525555
defaultInt uint32, min uint32, max uint32) {
@@ -691,6 +721,7 @@ type ConfigItemValue struct {
691721
StrValue string
692722
BoolValue bool
693723
TriStateValue TriState
724+
DurationValue time.Duration
694725
}
695726

696727
// StringValue - Returns the value in String Format
@@ -704,6 +735,8 @@ func (val ConfigItemValue) StringValue() string {
704735
return val.StrValue
705736
case ConfigItemTypeTriState:
706737
return FormatTriState(val.TriStateValue)
738+
case ConfigItemTypeDuration:
739+
return fmt.Sprintf("%d", uint64(val.DurationValue.Seconds()))
707740
default:
708741
return fmt.Sprintf("UnknownType(%d)", val.ItemType)
709742
}
@@ -771,6 +804,17 @@ func (configPtr *ConfigItemValueMap) GlobalValueInt(key GlobalSettingKey) uint32
771804
}
772805
}
773806

807+
// GlobalValueDuration - Gets a duration global setting value
808+
func (configPtr *ConfigItemValueMap) GlobalValueDuration(key GlobalSettingKey) time.Duration {
809+
val := configPtr.globalConfigItemValue(key)
810+
if val.ItemType == ConfigItemTypeDuration {
811+
return val.DurationValue
812+
} else {
813+
logrus.Fatalf("***Key(%s) is of Type(%d) NOT time.Duration", key, val.ItemType)
814+
return 0
815+
}
816+
}
817+
774818
// GlobalValueString - Gets a string global setting value
775819
func (configPtr *ConfigItemValueMap) GlobalValueString(key GlobalSettingKey) string {
776820
val := configPtr.globalConfigItemValue(key)
@@ -842,7 +886,7 @@ func (configPtr *ConfigItemValueMap) DelAgentValue(key AgentSettingKey, agentNam
842886
}
843887
}
844888

845-
// SetGlobalValueInt - sets a int value for a key
889+
// SetGlobalValueInt - sets an int value for a key
846890
func (configPtr *ConfigItemValueMap) SetGlobalValueInt(key GlobalSettingKey, value uint32) {
847891
if configPtr.GlobalSettings == nil {
848892
configPtr.GlobalSettings = make(map[GlobalSettingKey]ConfigItemValue)
@@ -896,22 +940,29 @@ func (configPtr *ConfigItemValueMap) ResetGlobalValue(key GlobalSettingKey) {
896940
configPtr.GlobalSettings[key] = specMap.GlobalSettings[key].DefaultValue()
897941
}
898942

943+
func (configSpec ConfigItemSpec) parseUint(itemValue string) (uint32, error) {
944+
i64, err := strconv.ParseUint(itemValue, 10, 32)
945+
if err == nil {
946+
val := uint32(i64)
947+
if val > configSpec.IntMax || val < configSpec.IntMin {
948+
retErr := fmt.Errorf("value out of bounds. Parsed value: %d, Max: %d, Min: %d",
949+
val, configSpec.IntMax, configSpec.IntMin)
950+
return val, retErr
951+
} else {
952+
return val, err
953+
}
954+
}
955+
956+
return 0, err
957+
}
958+
899959
func (configSpec ConfigItemSpec) parseValue(itemValue string) (ConfigItemValue, error) {
900960
value := configSpec.DefaultValue()
901961
var retErr error
902962
if configSpec.ItemType == ConfigItemTypeInt {
903-
i64, err := strconv.ParseUint(itemValue, 10, 32)
904-
if err == nil {
905-
val := uint32(i64)
906-
if val > configSpec.IntMax || val < configSpec.IntMin {
907-
retErr = fmt.Errorf("value out of bounds. Parsed value: %d, Max: %d, Min: %d",
908-
val, configSpec.IntMax, configSpec.IntMin)
909-
} else {
910-
value.IntValue = val
911-
}
912-
} else {
963+
value.IntValue, retErr = configSpec.parseUint(itemValue)
964+
if retErr != nil {
913965
value.IntValue = configSpec.IntDefault
914-
retErr = err
915966
}
916967
} else if configSpec.ItemType == ConfigItemTypeTriState {
917968
newTs, err := ParseTriState(itemValue)
@@ -936,6 +987,19 @@ func (configSpec ConfigItemSpec) parseValue(itemValue string) (ConfigItemValue,
936987
} else {
937988
return value, err
938989
}
990+
} else if configSpec.ItemType == ConfigItemTypeDuration {
991+
val, err := configSpec.parseUint(itemValue)
992+
if err == nil {
993+
if val > configSpec.IntMax || val < configSpec.IntMin {
994+
retErr = fmt.Errorf("value out of bounds. Parsed value: %d, Max: %d, Min: %d",
995+
val, configSpec.IntMax, configSpec.IntMin)
996+
} else {
997+
value.DurationValue = time.Duration(val * uint32(time.Second))
998+
}
999+
} else {
1000+
value.DurationValue = configSpec.DurationDefault
1001+
retErr = err
1002+
}
9391003
}
9401004
return value, retErr
9411005
}
@@ -959,7 +1023,7 @@ func NewConfigItemSpecMap() ConfigItemSpecMap {
9591023
configItemSpecMap.AddIntItem(ConfigInterval, 60, 5, HourInSec)
9601024
// Additional safety to periodically fetch the controller certificate
9611025
// Useful for odd cases when the triggered updates do not work.
962-
configItemSpecMap.AddIntItem(CertInterval, 24*HourInSec, 60, 0xFFFFFFFF)
1026+
configItemSpecMap.AddDurationItem(CertInterval, 24*time.Hour, 60*time.Second, maxDuration)
9631027
// timer.metric.diskscan.interval (seconds)
9641028
// Shorter interval can lead to device scanning the disk frequently which is a costly operation.
9651029
configItemSpecMap.AddIntItem(DiskScanMetricInterval, 300, 5, HourInSec)
@@ -969,7 +1033,7 @@ func NewConfigItemSpecMap() ConfigItemSpecMap {
9691033
configItemSpecMap.AddIntItem(MetricInterval, 60, 5, HourInSec)
9701034
// timer.metric.hardwarehealth.interval (seconds)
9711035
// Default value 12 hours minimum value 6 hours.
972-
configItemSpecMap.AddIntItem(HardwareHealthInterval, 43200, 21600, 0xFFFFFFFF)
1036+
configItemSpecMap.AddDurationItem(HardwareHealthInterval, 43200*time.Second, 21600*time.Second, maxDuration)
9731037
// timer.reboot.no.network (seconds) - reboot after no controller connectivity
9741038
// Max designed to allow the option of never rebooting even if device
9751039
// can't connect to the cloud

pkg/pillar/types/global_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ func TestDefaultValue(t *testing.T) {
2323
assert.Equal(t, item.TriStateDefault, defaultValue.TriStateValue)
2424
} else if item.ItemType == ConfigItemTypeString {
2525
assert.Equal(t, item.StringDefault, defaultValue.StrValue)
26+
} else if item.ItemType == ConfigItemTypeDuration {
27+
assert.Equal(t, item.DurationDefault, defaultValue.DurationValue)
2628
}
2729
}
2830

0 commit comments

Comments
 (0)