Skip to content

Commit 3b7aaf5

Browse files
feat: Allow deactivating of polling by setting a negative polling (#3205)
Signed-off-by: Thomas Poignant <thomas.poignant@gofeatureflag.org>
1 parent dd1f8ab commit 3b7aaf5

File tree

4 files changed

+60
-32
lines changed

4 files changed

+60
-32
lines changed

feature_flag.go

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,7 @@ func New(config Config) (*GoFeatureFlag, error) {
6161
case config.PollingInterval == 0:
6262
// The default value for the poll interval is 60 seconds
6363
config.PollingInterval = 60 * time.Second
64-
case config.PollingInterval < 0:
65-
// Check that value is not negative
66-
return nil, fmt.Errorf("%d is not a valid PollingInterval value, it need to be > 0", config.PollingInterval)
67-
case config.PollingInterval < time.Second:
64+
case config.PollingInterval > 0 && config.PollingInterval < time.Second:
6865
// the minimum value for the polling policy is 1 second
6966
config.PollingInterval = time.Second
7067
default:
@@ -89,7 +86,6 @@ func New(config Config) (*GoFeatureFlag, error) {
8986
notifiers = append(notifiers, &logsnotifier.Notifier{Logger: config.internalLogger})
9087

9188
notificationService := cache.NewNotificationService(notifiers)
92-
goFF.bgUpdater = newBackgroundUpdater(config.PollingInterval, config.EnablePollingJitter)
9389
goFF.cache = cache.New(notificationService, config.PersistentFlagConfigurationFile, config.internalLogger)
9490

9591
retrievers, err := config.GetRetrievers()
@@ -120,7 +116,10 @@ func New(config Config) (*GoFeatureFlag, error) {
120116
}
121117
}
122118

123-
go goFF.startFlagUpdaterDaemon()
119+
if config.PollingInterval > 0 {
120+
goFF.bgUpdater = newBackgroundUpdater(config.PollingInterval, config.EnablePollingJitter)
121+
go goFF.startFlagUpdaterDaemon()
122+
}
124123

125124
exporters := goFF.config.GetDataExporters()
126125
if len(exporters) > 0 {

feature_flag_test.go

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -75,15 +75,6 @@ func TestMultipleRetrieversWithOverrideFlag(t *testing.T) {
7575
assert.NotEqual(t, flag.ErrorCodeFlagNotFound, flagRes2.ErrorCode)
7676
}
7777

78-
func TestStartWithNegativeInterval(t *testing.T) {
79-
_, err := ffclient.New(ffclient.Config{
80-
PollingInterval: -60 * time.Second,
81-
Retriever: &fileretriever.Retriever{Path: "testdata/flag-config.yaml"},
82-
LeveledLogger: slog.Default(),
83-
})
84-
assert.Error(t, err)
85-
}
86-
8778
func TestStartWithMinInterval(t *testing.T) {
8879
_, err := ffclient.New(ffclient.Config{
8980
PollingInterval: 2,
@@ -743,3 +734,39 @@ func Test_DisableNotifierOnInit(t *testing.T) {
743734
})
744735
}
745736
}
737+
738+
func TestStartWithNegativeIntervalToDisablePolling(t *testing.T) {
739+
content, err := os.ReadFile("testdata/flag-config.yaml")
740+
assert.NoError(t, err)
741+
742+
// copy of the file
743+
tempFile, err := os.CreateTemp("", "")
744+
assert.NoError(t, err)
745+
defer func() { _ = os.Remove(tempFile.Name()) }()
746+
err = os.WriteFile(tempFile.Name(), content, os.ModePerm)
747+
assert.NoError(t, err)
748+
749+
goff, err := ffclient.New(ffclient.Config{
750+
PollingInterval: -1 * time.Second,
751+
Retriever: &fileretriever.Retriever{Path: tempFile.Name()},
752+
LeveledLogger: slog.Default(),
753+
})
754+
assert.NoError(t, err)
755+
756+
cacheRefresh := goff.GetCacheRefreshDate()
757+
758+
// modify the file to trigger a refresh
759+
newContent, err := os.ReadFile("testdata/flag-config-2nd-file.yaml")
760+
assert.NoError(t, err)
761+
err = os.WriteFile(tempFile.Name(), newContent, os.ModePerm)
762+
assert.NoError(t, err)
763+
764+
// wait to be sure we give time to the goroutine to refresh the cache
765+
time.Sleep(2 * time.Second)
766+
767+
assert.Equal(t, cacheRefresh, goff.GetCacheRefreshDate())
768+
769+
// we force a refresh to check if the cache is refreshed
770+
goff.ForceRefresh()
771+
assert.NotEqual(t, cacheRefresh, goff.GetCacheRefreshDate())
772+
}

0 commit comments

Comments
 (0)