Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
08abc7e
chore: Pipe headers through data sources.
kinyoklion Jan 21, 2026
bd15015
Merge branch 'main' into rlamb/connect-headers-to-data-sources
kinyoklion Jan 21, 2026
b20c621
Cleanup
kinyoklion Jan 21, 2026
b46ac5e
chore: Add fallback and recovery support for FDv2.
kinyoklion Jan 23, 2026
fba5aa2
Extract conditions from FDv2DataSource.
kinyoklion Jan 23, 2026
472a1d2
Extract synchronizer state management from the FDv2DataSource.
kinyoklion Jan 23, 2026
0c150a1
Add recovery condition tests.
kinyoklion Jan 23, 2026
5888761
Merge branch 'main' into rlamb/fallback-and-recovery
kinyoklion Jan 26, 2026
9e79c00
Merge branch 'rlamb/fallback-and-recovery' of github.com:launchdarkly…
kinyoklion Jan 26, 2026
33fa6c5
Closeable synchronizer state manager.
kinyoklion Jan 26, 2026
ec0d0ec
More clean shutdown model.
kinyoklion Jan 26, 2026
5b62238
SynchronizerStateManager tests.
kinyoklion Jan 26, 2026
53ea319
FDv2DataSource tests.
kinyoklion Jan 26, 2026
147556d
Add documentation to long-running test.
kinyoklion Jan 26, 2026
321fb4f
Fix test expectations.
kinyoklion Jan 26, 2026
1234bc9
Remove un-needed synchronizer.
kinyoklion Jan 27, 2026
4fa930a
chore: adds conditional persistence propagation
tanderson-ld Jan 27, 2026
28bb3ca
Merge remote-tracking branch 'origin/main' into ta/SDK-1622/persisten…
tanderson-ld Jan 27, 2026
10cab33
Correct lock on getNextAvailableSynchronizer.
kinyoklion Jan 27, 2026
382246d
PR Feedback.
kinyoklion Jan 27, 2026
e6b032e
Correct prime synchronizer logic.
kinyoklion Jan 27, 2026
6e14b7f
fixing volatile issue
tanderson-ld Jan 27, 2026
e507aeb
Merge remote-tracking branch 'origin/rlamb/fallback-and-recovery' int…
tanderson-ld Jan 27, 2026
996036d
chore: handles offline mode, no initializers nor synchronizers
tanderson-ld Jan 28, 2026
8dfeadb
Merge remote-tracking branch 'origin' into ta/SDK-1611/daemon-mode-of…
tanderson-ld Jan 29, 2026
14e4f25
Merge remote-tracking branch 'origin/main' into ta/SDK-1611/daemon-mo…
tanderson-ld Jan 30, 2026
f65ddd4
bot review
tanderson-ld Jan 30, 2026
6ae877b
bot review
tanderson-ld Jan 30, 2026
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
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,9 @@ public boolean init(DataStoreTypes.FullDataSet<DataStoreTypes.ItemDescriptor> al
DataStoreTypes.ChangeSetType.Full,
Selector.EMPTY,
allData.getData(),
null);
null,
allData.shouldPersist()
);
resultQueue.put(FDv2SourceResult.changeSet(changeSet, false));
return true;
}
Expand All @@ -153,7 +155,9 @@ public boolean upsert(DataStoreTypes.DataKind kind, String key, DataStoreTypes.I
DataStoreTypes.ChangeSetType.Partial,
Selector.EMPTY,
data,
null);
null,
true // default to true as this adapter is used for adapting FDv1 data sources which are always persistent
);
resultQueue.put(FDv2SourceResult.changeSet(changeSet, false));
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ private void run() {
if (!sourceManager.hasAvailableSources()) {
// There are not any initializer or synchronizers, so we are at the best state that
// can be achieved.
logger.info("LaunchDarkly client will not connect to Launchdarkly for feature flag data due to no initializers or synchronizers");
dataSourceUpdates.updateStatus(DataSourceStatusProvider.State.VALID, null);
startFuture.complete(true);
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import com.launchdarkly.sdk.server.subsystems.DataStore;
import com.launchdarkly.sdk.server.subsystems.LoggingConfiguration;
import com.launchdarkly.sdk.server.subsystems.DataSystemConfiguration;
import com.launchdarkly.sdk.server.subsystems.ComponentConfigurer;

import java.io.Closeable;
import java.io.IOException;
Expand Down Expand Up @@ -167,15 +166,21 @@ static FDv2DataSystem create(
};
}

DataSource dataSource = new FDv2DataSource(
initializerFactories,
synchronizerFactories,
fdv1FallbackFactory,
dataSourceUpdates,
config.threadPriority,
clientContext.getBaseLogger().subLogger(Loggers.DATA_SOURCE_LOGGER_NAME),
clientContext.sharedExecutor
);
final DataSource dataSource;
if (config.offline) {
dataSource = Components.externalUpdatesOnly().build(clientContext.withDataSourceUpdateSink(dataSourceUpdates));
} else {
dataSource = new FDv2DataSource(
initializerFactories,
synchronizerFactories,
fdv1FallbackFactory,
dataSourceUpdates,
config.threadPriority,
clientContext.getBaseLogger().subLogger(Loggers.DATA_SOURCE_LOGGER_NAME),
clientContext.sharedExecutor
);
}

DataSourceStatusProvider dataSourceStatusProvider = new DataSourceStatusProviderImpl(
dataSourceStatusBroadcaster,
dataSourceUpdates);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,8 @@ public void init(FullDataSet<ItemDescriptor> allData) {
maybeSwitchStore();

// Only write to persistent store if shouldPersist is true and store is in READ_WRITE mode
if (persistenceMode == DataStoreMode.READ_WRITE && allData.shouldPersist()) {
if (persistentStore != null) {
persistentStore.init(allData);
}
if (hasPersistence && persistenceMode == DataStoreMode.READ_WRITE && allData.shouldPersist()) {
persistentStore.init(allData);
}
}

Expand Down Expand Up @@ -97,12 +95,12 @@ public boolean isInitialized() {

@Override
public boolean isStatusMonitoringEnabled() {
return persistentStore != null ? persistentStore.isStatusMonitoringEnabled() : false;
return hasPersistence ? persistentStore.isStatusMonitoringEnabled() : false;
}

@Override
public CacheStats getCacheStats() {
return persistentStore != null ? persistentStore.getCacheStats() : null;
return hasPersistence ? persistentStore.getCacheStats() : null;
}

@Override
Expand Down Expand Up @@ -135,7 +133,7 @@ public Selector getSelector() {
@Override
public void close() throws IOException {
memoryStore.close();
if (persistentStore != null) {
if (hasPersistence) {
persistentStore.close();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.google.common.collect.ImmutableMap;
import com.launchdarkly.sdk.LDContext;
import com.launchdarkly.sdk.LDValue;
import com.launchdarkly.sdk.server.integrations.DataSystemModes;
import com.launchdarkly.sdk.server.interfaces.DataSourceStatusProvider;
import com.launchdarkly.sdk.server.subsystems.DataStore;

Expand Down Expand Up @@ -78,4 +79,17 @@ public void offlineClientGetsFlagsStateFromDataStore() throws IOException {
assertEquals(ImmutableMap.<String, LDValue>of("key", LDValue.of(true)), state.toValuesMap());
}
}
}

@Test
public void offlineWithFDv2DataSystemIsInitializedAndReportsValidStatus() throws IOException {
LDConfig config = baseConfig()
.dataSystem(new DataSystemModes().defaultMode())
.offline(true)
.build();
try (LDClient client = new LDClient("SDK_KEY", config)) {
assertTrue(client.dataSystem instanceof FDv2DataSystem);
assertTrue(client.isInitialized());
assertEquals(DataSourceStatusProvider.State.VALID, client.getDataSourceStatusProvider().getStatus().getState());
}
}
}