From cb9784bdbb2fad2bee17242b2e569c9da0c318a0 Mon Sep 17 00:00:00 2001 From: Lindsey Cheng Date: Fri, 30 Jun 2023 08:59:45 +0800 Subject: [PATCH] fix: Add warn log for create/update interval Add warn log for interval value from Interval and AutoEvent if the value is less than the suggested value. Closes #4586. Signed-off-by: Lindsey Cheng --- internal/core/metadata/application/device.go | 14 ++++++++ internal/pkg/utils/time.go | 34 ++++++++++++++++++ internal/pkg/utils/time_test.go | 35 +++++++++++++++++++ .../support/scheduler/application/interval.go | 12 ++++++- 4 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 internal/pkg/utils/time.go create mode 100644 internal/pkg/utils/time_test.go diff --git a/internal/core/metadata/application/device.go b/internal/core/metadata/application/device.go index 4fc3787024..85bc03026e 100644 --- a/internal/core/metadata/application/device.go +++ b/internal/core/metadata/application/device.go @@ -31,8 +31,12 @@ import ( "github.com/edgexfoundry/edgex-go/internal/core/metadata/container" "github.com/edgexfoundry/edgex-go/internal/core/metadata/infrastructure/interfaces" "github.com/edgexfoundry/edgex-go/internal/pkg/correlation" + "github.com/edgexfoundry/edgex-go/internal/pkg/utils" ) +// the suggested minimum duration string for auto event interval +const minAutoEventInterval = "1ms" + // The AddDevice function accepts the new device model from the controller function // and then invokes AddDevice function of infrastructure layer to add new device func AddDevice(d models.Device, ctx context.Context, dic *di.Container) (id string, edgeXerr errors.EdgeX) { @@ -63,6 +67,11 @@ func AddDevice(d models.Device, ctx context.Context, dic *di.Container) (id stri correlation.FromContext(ctx), ) + // If device is successfully created, check each AutoEvent interval value and display a warning if it's smaller than the suggested 10ms value + for _, autoEvent := range d.AutoEvents { + utils.CheckMinInterval(autoEvent.Interval, minAutoEventInterval, lc) + } + deviceDTO := dtos.FromDeviceModelToDTO(addedDevice) go publishSystemEvent(common.DeviceSystemEventType, common.SystemEventActionAdd, d.ServiceName, deviceDTO, ctx, dic) @@ -162,6 +171,11 @@ func PatchDevice(dto dtos.UpdateDevice, ctx context.Context, dic *di.Container) return errors.NewCommonEdgeXWrapper(err) } + // If device is successfully updated, check each AutoEvent interval value and display a warning if it's smaller than the suggested 10ms value + for _, autoEvent := range device.AutoEvents { + utils.CheckMinInterval(autoEvent.Interval, minAutoEventInterval, lc) + } + lc.Debugf( "Device patched on DB successfully. Correlation-ID: %s ", correlation.FromContext(ctx), diff --git a/internal/pkg/utils/time.go b/internal/pkg/utils/time.go new file mode 100644 index 0000000000..4e70ee96f4 --- /dev/null +++ b/internal/pkg/utils/time.go @@ -0,0 +1,34 @@ +// +// Copyright (C) 2023 IOTech Ltd +// +// SPDX-License-Identifier: Apache-2.0 + +package utils + +import ( + "time" + + "github.com/edgexfoundry/go-mod-core-contracts/v3/clients/logger" +) + +// CheckMinInterval parses the ISO 8601 time duration string to Duration type +// and evaluates if the duration value is smaller than the suggested minimum duration string +func CheckMinInterval(value string, min string, lc logger.LoggingClient) bool { + valueDuration, err := time.ParseDuration(value) + if err != nil { + lc.Errorf("failed to parse the interval duration string %s to a duration time value: %v", value, err) + return false + } + minDuration, err := time.ParseDuration(min) + if err != nil { + lc.Errorf("failed to parse the minimum duration string %s to a duration time value: %v", value, err) + return false + } + + if valueDuration < minDuration { + // the duration value is smaller than the min + lc.Warnf("the interval value '%s' is smaller than the suggested value '%s', which might cause abnormal CPU increase", valueDuration, minDuration) + return false + } + return true +} diff --git a/internal/pkg/utils/time_test.go b/internal/pkg/utils/time_test.go new file mode 100644 index 0000000000..062bf82dd2 --- /dev/null +++ b/internal/pkg/utils/time_test.go @@ -0,0 +1,35 @@ +// +// Copyright (C) 2023 IOTech Ltd +// +// SPDX-License-Identifier: Apache-2.0 + +package utils + +import ( + "testing" + + "github.com/edgexfoundry/go-mod-core-contracts/v3/clients/logger" + + "github.com/stretchr/testify/assert" +) + +func TestCheckMinInterval(t *testing.T) { + lc := logger.NewMockClient() + + tests := []struct { + name string + interval string + min string + result bool + }{ + {"valid - interval is bigger than the minimum value", "1s", "10ms", true}, + {"invalid - interval is smaller than the minimum value", "100us", "1ms", false}, + {"invalid - parsing duration string failed", "INVALID", "1ms", false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := CheckMinInterval(tt.interval, tt.min, lc) + assert.Equal(t, tt.result, result) + }) + } +} diff --git a/internal/support/scheduler/application/interval.go b/internal/support/scheduler/application/interval.go index e16d020cf3..23c43019e1 100644 --- a/internal/support/scheduler/application/interval.go +++ b/internal/support/scheduler/application/interval.go @@ -1,5 +1,5 @@ // -// Copyright (C) 2021 IOTech Ltd +// Copyright (C) 2021-2023 IOTech Ltd // // SPDX-License-Identifier: Apache-2.0 @@ -10,6 +10,7 @@ import ( "fmt" "github.com/edgexfoundry/edgex-go/internal/pkg/correlation" + "github.com/edgexfoundry/edgex-go/internal/pkg/utils" "github.com/edgexfoundry/edgex-go/internal/support/scheduler/container" "github.com/edgexfoundry/edgex-go/internal/support/scheduler/infrastructure/interfaces" @@ -22,6 +23,9 @@ import ( "github.com/edgexfoundry/go-mod-core-contracts/v3/models" ) +// the suggested minimum duration string for scheduler interval +const minSchedulerInterval = "10ms" + // The AddInterval function accepts the new Interval model from the controller function // and then invokes AddInterval function of infrastructure layer to add new Interval func AddInterval(interval models.Interval, ctx context.Context, dic *di.Container) (id string, edgeXerr errors.EdgeX) { @@ -41,6 +45,9 @@ func AddInterval(interval models.Interval, ctx context.Context, dic *di.Containe addedInterval.Id, correlation.FromContext(ctx)) + // If interval is successfully created, check the interval value and display a warning if it's smaller than the suggested 10ms value + utils.CheckMinInterval(interval.Interval, minSchedulerInterval, lc) + return addedInterval.Id, nil } @@ -116,6 +123,9 @@ func PatchInterval(dto dtos.UpdateInterval, ctx context.Context, dic *di.Contain return errors.NewCommonEdgeXWrapper(err) } + // If interval is successfully updated, check the interval value and display a warning if it's smaller than the suggested 10ms value + utils.CheckMinInterval(interval.Interval, minSchedulerInterval, lc) + lc.Debugf( "Interval patched on DB successfully. Correlation-ID: %s ", correlation.FromContext(ctx),