diff --git a/internal/datasystem/data_availability.go b/internal/datasystem/data_availability.go index 5e0fecbd..6fb8e360 100644 --- a/internal/datasystem/data_availability.go +++ b/internal/datasystem/data_availability.go @@ -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) +} diff --git a/internal/datasystem/data_availability_test.go b/internal/datasystem/data_availability_test.go new file mode 100644 index 00000000..bb35e14c --- /dev/null +++ b/internal/datasystem/data_availability_test.go @@ -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)) +} diff --git a/internal/datasystem/fdv1_datasystem.go b/internal/datasystem/fdv1_datasystem.go index abc649e2..1dafcd9f 100644 --- a/internal/datasystem/fdv1_datasystem.go +++ b/internal/datasystem/fdv1_datasystem.go @@ -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 diff --git a/internal/datasystem/fdv2_datasystem.go b/internal/datasystem/fdv2_datasystem.go index 281f6da1..c3a93b86 100644 --- a/internal/datasystem/fdv2_datasystem.go +++ b/internal/datasystem/fdv2_datasystem.go @@ -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 diff --git a/ldclient.go b/ldclient.go index fb0926bb..aa77c762 100644 --- a/ldclient.go +++ b/ldclient.go @@ -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 ( @@ -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 diff --git a/ldcomponents/data_system_configuration_builder.go b/ldcomponents/data_system_configuration_builder.go index 695ad20a..349cd1ef 100644 --- a/ldcomponents/data_system_configuration_builder.go +++ b/ldcomponents/data_system_configuration_builder.go @@ -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{},