Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pkg/client/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ func (f OptimizelyFactory) Client(clientOptions ...OptionFunc) (*OptimizelyClien

// Initialize the default services with the execution context
if pollingConfigManager, ok := appClient.ConfigManager.(*config.PollingProjectConfigManager); ok {
pollingConfigManager.Start(f.SDKKey, appClient.executionCtx)
pollingConfigManager.Start(appClient.executionCtx)
}

if batchProcessor, ok := appClient.EventProcessor.(*event.BatchEventProcessor); ok {
Expand Down
20 changes: 11 additions & 9 deletions pkg/config/polling_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,13 @@ var cmLogger = logging.GetLogger("PollingConfigManager")
// PollingProjectConfigManager maintains a dynamic copy of the project config by continuously polling for the datafile
// from the Optimizely CDN at a given (configurable) interval.
type PollingProjectConfigManager struct {
requester utils.Requester
pollingInterval time.Duration
notificationCenter notification.Center
datafileURLTemplate string
initDatafile []byte
lastModified string
datafileURLTemplate string
notificationCenter notification.Center
pollingInterval time.Duration
requester utils.Requester
sdkKey string

configLock sync.RWMutex
err error
Expand Down Expand Up @@ -94,7 +95,7 @@ func WithInitialDatafile(datafile []byte) OptionFunc {
}

// SyncConfig gets current datafile and updates projectConfig
func (cm *PollingProjectConfigManager) SyncConfig(sdkKey string, datafile []byte) {
func (cm *PollingProjectConfigManager) SyncConfig(datafile []byte) {
var e error
var code int
var respHeaders http.Header
Expand All @@ -104,7 +105,7 @@ func (cm *PollingProjectConfigManager) SyncConfig(sdkKey string, datafile []byte
cm.configLock.Unlock()
}

url := fmt.Sprintf(cm.datafileURLTemplate, sdkKey)
url := fmt.Sprintf(cm.datafileURLTemplate, cm.sdkKey)
if len(datafile) == 0 {
if cm.lastModified != "" {
lastModifiedHeader := utils.Header{Name: ModifiedSince, Value: cm.lastModified}
Expand Down Expand Up @@ -170,14 +171,14 @@ func (cm *PollingProjectConfigManager) SyncConfig(sdkKey string, datafile []byte
}

// Start starts the polling
func (cm *PollingProjectConfigManager) Start(sdkKey string, exeCtx utils.ExecutionCtx) {
func (cm *PollingProjectConfigManager) Start(exeCtx utils.ExecutionCtx) {
go func() {
cmLogger.Debug("Polling Config Manager Initiated")
t := time.NewTicker(cm.pollingInterval)
for {
select {
case <-t.C:
cm.SyncConfig(sdkKey, []byte{})
cm.SyncConfig([]byte{})
case <-exeCtx.GetContext().Done():
cmLogger.Debug("Polling Config Manager Stopped")
return
Expand All @@ -194,14 +195,15 @@ func NewPollingProjectConfigManager(sdkKey string, pollingMangerOptions ...Optio
pollingInterval: DefaultPollingInterval,
requester: utils.NewHTTPRequester(),
datafileURLTemplate: DatafileURLTemplate,
sdkKey: sdkKey,
}

for _, opt := range pollingMangerOptions {
opt(&pollingProjectConfigManager)
}

initDatafile := pollingProjectConfigManager.initDatafile
pollingProjectConfigManager.SyncConfig(sdkKey, initDatafile) // initial poll
pollingProjectConfigManager.SyncConfig(initDatafile) // initial poll
return &pollingProjectConfigManager
}

Expand Down
30 changes: 15 additions & 15 deletions pkg/config/polling_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func TestNewPollingProjectConfigManagerWithOptions(t *testing.T) {

exeCtx := utils.NewCancelableExecutionCtx()
configManager := NewPollingProjectConfigManager(sdkKey, WithRequester(mockRequester))
configManager.Start(sdkKey, exeCtx)
configManager.Start(exeCtx)
mockRequester.AssertExpectations(t)

actual, err := configManager.GetConfig()
Expand All @@ -72,7 +72,7 @@ func TestNewPollingProjectConfigManagerWithNull(t *testing.T) {

exeCtx := utils.NewCancelableExecutionCtx()
configManager := NewPollingProjectConfigManager(sdkKey, WithRequester(mockRequester))
configManager.Start(sdkKey, exeCtx)
configManager.Start(exeCtx)
mockRequester.AssertExpectations(t)

_, err := configManager.GetConfig()
Expand All @@ -90,15 +90,15 @@ func TestNewPollingProjectConfigManagerWithSimilarDatafileRevisions(t *testing.T

exeCtx := utils.NewCancelableExecutionCtx()
configManager := NewPollingProjectConfigManager(sdkKey, WithRequester(mockRequester))
configManager.Start(sdkKey, exeCtx)
configManager.Start(exeCtx)
mockRequester.AssertExpectations(t)

actual, err := configManager.GetConfig()
assert.Nil(t, err)
assert.NotNil(t, actual)
assert.Equal(t, projectConfig1, actual)

configManager.SyncConfig(sdkKey, mockDatafile2)
configManager.SyncConfig(mockDatafile2)
actual, err = configManager.GetConfig()
assert.Equal(t, projectConfig1, actual)
}
Expand All @@ -118,7 +118,7 @@ func TestNewPollingProjectConfigManagerWithLastModifiedDates(t *testing.T) {

exeCtx := utils.NewCancelableExecutionCtx()
configManager := NewPollingProjectConfigManager(sdkKey, WithRequester(mockRequester))
configManager.Start(sdkKey, exeCtx)
configManager.Start(exeCtx)

// Fetch valid config
actual, err := configManager.GetConfig()
Expand All @@ -127,7 +127,7 @@ func TestNewPollingProjectConfigManagerWithLastModifiedDates(t *testing.T) {
assert.Equal(t, projectConfig1, actual)

// Sync and check no changes were made to the previous config because of 304 error code
configManager.SyncConfig(sdkKey, []byte{})
configManager.SyncConfig([]byte{})
actual, err = configManager.GetConfig()
assert.Nil(t, err)
assert.NotNil(t, actual)
Expand All @@ -148,15 +148,15 @@ func TestNewPollingProjectConfigManagerWithDifferentDatafileRevisions(t *testing

exeCtx := utils.NewCancelableExecutionCtx()
configManager := NewPollingProjectConfigManager(sdkKey, WithRequester(mockRequester))
configManager.Start(sdkKey, exeCtx)
configManager.Start(exeCtx)
mockRequester.AssertExpectations(t)

actual, err := configManager.GetConfig()
assert.Nil(t, err)
assert.NotNil(t, actual)
assert.Equal(t, projectConfig1, actual)

configManager.SyncConfig(sdkKey, mockDatafile2)
configManager.SyncConfig(mockDatafile2)
actual, err = configManager.GetConfig()
assert.Equal(t, projectConfig2, actual)
}
Expand All @@ -175,20 +175,20 @@ func TestNewPollingProjectConfigManagerWithErrorHandling(t *testing.T) {

exeCtx := utils.NewCancelableExecutionCtx()
configManager := NewPollingProjectConfigManager(sdkKey, WithRequester(mockRequester))
configManager.Start(sdkKey, exeCtx)
configManager.Start(exeCtx)
mockRequester.AssertExpectations(t)

actual, err := configManager.GetConfig() // polling for bad file
assert.NotNil(t, err)
assert.Nil(t, actual)
assert.Nil(t, projectConfig1)

configManager.SyncConfig(sdkKey, mockDatafile2) // polling for good file
configManager.SyncConfig(mockDatafile2) // polling for good file
actual, err = configManager.GetConfig()
assert.Nil(t, err)
assert.Equal(t, projectConfig2, actual)

configManager.SyncConfig(sdkKey, mockDatafile1) // polling for bad file, error not null but good project
configManager.SyncConfig(mockDatafile1) // polling for bad file, error not null but good project
actual, err = configManager.GetConfig()
assert.Nil(t, err)
assert.Equal(t, projectConfig2, actual)
Expand All @@ -206,7 +206,7 @@ func TestNewPollingProjectConfigManagerOnDecision(t *testing.T) {

exeCtx := utils.NewCancelableExecutionCtx()
configManager := NewPollingProjectConfigManager(sdkKey, WithRequester(mockRequester))
configManager.Start(sdkKey, exeCtx)
configManager.Start(exeCtx)

var numberOfCalls = 0
callback := func(notification notification.ProjectConfigUpdateNotification) {
Expand All @@ -219,7 +219,7 @@ func TestNewPollingProjectConfigManagerOnDecision(t *testing.T) {
assert.Nil(t, err)
assert.NotNil(t, actual)

configManager.SyncConfig(sdkKey, mockDatafile2)
configManager.SyncConfig(mockDatafile2)
actual, err = configManager.GetConfig()
assert.Nil(t, err)
assert.NotNil(t, actual)
Expand All @@ -240,7 +240,7 @@ func TestPollingInterval(t *testing.T) {

exeCtx := utils.NewCancelableExecutionCtx()
configManager := NewPollingProjectConfigManager(sdkKey, WithPollingInterval(5*time.Second))
configManager.Start(sdkKey, exeCtx)
configManager.Start(exeCtx)

assert.Equal(t, configManager.pollingInterval, 5*time.Second)
}
Expand All @@ -250,7 +250,7 @@ func TestInitialDatafile(t *testing.T) {
sdkKey := "test_sdk_key"
exeCtx := utils.NewCancelableExecutionCtx()
configManager := NewPollingProjectConfigManager(sdkKey, WithInitialDatafile([]byte("test")))
configManager.Start(sdkKey, exeCtx)
configManager.Start(exeCtx)

assert.Equal(t, configManager.initDatafile, []byte("test"))
}
Expand Down