Skip to content

Commit

Permalink
chore: Fail initialization if data system doesn't archive target avai…
Browse files Browse the repository at this point in the history
…lability (#232)
  • Loading branch information
keelerm84 authored Jan 3, 2025
1 parent 9aa1e65 commit a8a16c3
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 6 deletions.
10 changes: 10 additions & 0 deletions internal/datasystem/data_availability.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,13 @@ const (
// Refreshed means the SDK has obtained, at least once, the latest known data from LaunchDarkly.
Refreshed = DataAvailability("refreshed")
)

// AtLeast returns true if the DataAvailability is at least as good as the
// other DataAvailability in terms of data quality.
func (da DataAvailability) AtLeast(other DataAvailability) bool {
if da == other {
return true
}

return da == Refreshed || (da == Cached && other == Defaults)
}
21 changes: 21 additions & 0 deletions internal/datasystem/data_availability_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package datasystem

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestDataAvailibilityAtLeast(t *testing.T) {
assert.True(t, Refreshed.AtLeast(Refreshed))
assert.True(t, Refreshed.AtLeast(Cached))
assert.True(t, Refreshed.AtLeast(Defaults))

assert.False(t, Cached.AtLeast(Refreshed))
assert.True(t, Cached.AtLeast(Cached))
assert.True(t, Cached.AtLeast(Defaults))

assert.False(t, Defaults.AtLeast(Refreshed))
assert.False(t, Defaults.AtLeast(Cached))
assert.True(t, Defaults.AtLeast(Defaults))
}
5 changes: 5 additions & 0 deletions internal/datasystem/fdv1_datasystem.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,11 @@ func (f *FDv1) DataAvailability() DataAvailability {
return Defaults
}

//nolint:revive // Data system implementation.
func (f *FDv1) TargetAvailability() DataAvailability {
return Refreshed
}

//nolint:revive // Data system implementation.
func (f *FDv1) Store() subsystems.ReadOnlyStore {
return f.dataStore
Expand Down
13 changes: 12 additions & 1 deletion internal/datasystem/fdv2_datasystem.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,12 +262,23 @@ func (f *FDv2) DataAvailability() DataAvailability {
if f.store.Selector().IsDefined() {
return Refreshed
}
if f.store.IsInitialized() {

if !f.hasDataSources() || f.store.IsInitialized() {
return Cached
}

return Defaults
}

//nolint:revive // DataSystem method.
func (f *FDv2) TargetAvailability() DataAvailability {
if f.hasDataSources() {
return Refreshed
}

return Cached
}

//nolint:revive // DataSystem method.
func (f *FDv2) DataSourceStatusBroadcaster() *internal.Broadcaster[interfaces.DataSourceStatus] {
return f.broadcasters.dataSourceStatus
Expand Down
14 changes: 9 additions & 5 deletions ldclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ type dataSystem interface {

// DataAvailability indicates what form of data is available.
DataAvailability() datasystem.DataAvailability

/// TargetAvailability indicates the ideal form of data available.
TargetAvailability() datasystem.DataAvailability
}

var (
Expand Down Expand Up @@ -342,13 +345,14 @@ func MakeCustomClient(sdkKey string, config Config, waitFor time.Duration) (*LDC
for {
select {
case <-closeWhenReady:
if client.dataSystem.DataAvailability() != datasystem.Refreshed {
loggers.Warn("LaunchDarkly client initialization failed")
return client, ErrInitializationFailed
if client.dataSystem.DataAvailability().AtLeast(client.dataSystem.TargetAvailability()) {
loggers.Info("Initialized LaunchDarkly client")
return client, nil
}

loggers.Info("Initialized LaunchDarkly client")
return client, nil
loggers.Warn("LaunchDarkly client initialization failed")
return client, ErrInitializationFailed

case <-timeout:
loggers.Warn("Timeout encountered waiting for LaunchDarkly client initialization")
go func() { <-closeWhenReady }() // Don't block the DataSource when not waiting
Expand Down
1 change: 1 addition & 0 deletions ldcomponents/data_system_configuration_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ func (d *DataSystemConfigurationBuilder) Build(
}
conf.Store = store
}
conf.StoreMode = d.storeMode
for i, initializerBuilder := range d.initializerBuilders {
if initializerBuilder == nil {
return ss.DataSystemConfiguration{},
Expand Down

0 comments on commit a8a16c3

Please sign in to comment.