Skip to content

feat!: Remove the FDv1 data system - #487

Open
keelerm84 wants to merge 8 commits into
mk/SDK-3471/specs-on-fdv2from
mk/SDK-3474/remove-fdv1
Open

keelerm84 wants to merge 8 commits into
mk/SDK-3471/specs-on-fdv2from
mk/SDK-3474/remove-fdv1

Conversation

@keelerm84

@keelerm84 keelerm84 commented Nov 5, 2026 •

Copy link
Copy Markdown
Member

fix: Enforce the 30 second minimum poll interval in the polling builders

Summary

The client now always uses the FDv2 data system. When data_system_config
is nil, it uses DataSystem.default.

Removed config options: stream, use_ldd, poll_interval,
initial_reconnect_delay, base_uri, stream_uri, feature_store,
data_source, cache_store, payload_filter_key and data_source_update_sink.
Use the data system builders in their place: DataSystem.persistent_store
or DataSystem.daemon for a persistent store, and the polling and
streaming builders for URIs and intervals.

Removed classes and methods: the v1 TestData and its FlagBuilder,
FileData.data_source, InMemoryFeatureStore, the FDv1 data source mixin
in Interfaces::DataSource, and the Interfaces::DataSource::UpdateSink
and Interfaces::DataStore::UpdateSink interfaces. Use TestDataV2 and
FileData.data_source_v2. LaunchDarkly::Integrations now loads
TestDataV2.

The SDK key is required unless the client is offline, or events are
disabled and no data source connects to LaunchDarkly. Daemon mode is a
data system with no initializers or synchronizers. With events disabled
it reports initialized and a fork does not break it, as LDD mode did.

The diagnostic init event no longer reports customBaseURI,
customStreamURI, pollingIntervalMillis, streamingDisabled or
usingRelayDaemon. The FDv2 fields are still to be decided before 9.0.

The FDv1 fallback that FDv2 uses stays. UnexpectedResponseError moves to
Impl::DataSystem with the FDv2 polling code.

The FDv2 polling builder and the FDv1 fallback polling builder replace
a poll interval below 30 seconds with 30 seconds and log a warning. The
removed poll_interval config option had the same minimum. Without it, a
small or zero interval polls LaunchDarkly in a tight loop.

The test service no longer maps the top-level streaming, polling and
persistentDataStore settings that harness v2 sends, and no longer reports
the filtering, filtering-strict and retry-conformance-fdv1 capabilities.
Harness v3 sends a dataSystem block for every test. A client with no
dataSystem block gets a data system with no sources, as LDD mode did.

CI and the Makefile run harness v3 only.

  • The FDv2 and FDv1 fallback HTTP polling requesters: request headers,
    ETag and 304, gzip, the basis parameter, error status, response
    headers and proxy.
  • PollingDataSource#stop ends a long interval wait.
  • FileData v2: YAML with a Ruby object and file paths with shell
    metacharacters do not run code, reload without the listen gem, an
    initial sync failure, full flags from flagValues, and evaluation
    through LDClient.
  • Every FlagBuilderV2 and FlagRuleBuilderV2 method.
  • Streaming sync error paths, and the environment ID through the real
    on_connect handler in place of a copy of its logic.
  • The FeatureStoreClientWrapperV2 availability poller.
  • FDv2 data availability: CACHED, DEFAULTS and daemon mode.
  • StatusProviderV2 listener notifications.

Note

Overview
Breaking: the Ruby SDK now only runs the FDv2 data path. LDClient always builds DataSystem.default when data_system_config is omitted, and drops the entire FDv1 layer (legacy stream/poll processors, InMemoryFeatureStore, store wrappers, file/test data v1, Interfaces::DataSource::UpdateSink, etc.).

Config & integrations: top-level options like stream, use_ldd, poll_interval, base_uri/stream_uri, feature_store, data_source, cache_store, and payload_filter_key are removed—callers must use DataSystem builders (persistent_store, daemon, streaming/polling builders, FileData.data_source_v2, TestDataV2). SDK key rules, fork warnings, and initialized? semantics change to match “no remote sources unless configured.”

Behavior & tooling: FDv2 polling builders clamp sub-30s poll intervals (with warnings), move UnexpectedResponseError alongside FDv2 polling, trim diagnostic init fields tied to FDv1, and update contract tests/CI/Makefile to harness v3 only with slimmer advertised capabilities.

Reviewed by Cursor Bugbot for commit c7a8ee3. Bugbot is set up for automated code reviews on this repo. Configure here.

The test service no longer maps the top-level streaming, polling and
persistentDataStore settings that harness v2 sends, and no longer reports
the filtering, filtering-strict and retry-conformance-fdv1 capabilities.
Harness v3 sends a dataSystem block for every test. A client with no
dataSystem block gets a data system with no sources, as LDD mode did.

CI and the Makefile run harness v3 only.
The client now always uses the FDv2 data system. When data_system_config
is nil, it uses DataSystem.default.

Removed config options: stream, use_ldd, poll_interval,
initial_reconnect_delay, base_uri, stream_uri, feature_store,
data_source, cache_store, payload_filter_key and data_source_update_sink.
Use the data system builders in their place: DataSystem.persistent_store
or DataSystem.daemon for a persistent store, and the polling and
streaming builders for URIs and intervals.

Removed classes and methods: the v1 TestData and its FlagBuilder,
FileData.data_source, InMemoryFeatureStore, the FDv1 data source mixin
in Interfaces::DataSource, and the Interfaces::DataSource::UpdateSink
and Interfaces::DataStore::UpdateSink interfaces. Use TestDataV2 and
FileData.data_source_v2. LaunchDarkly::Integrations now loads
TestDataV2.

The SDK key is required unless the client is offline, or events are
disabled and no data source connects to LaunchDarkly. Daemon mode is a
data system with no initializers or synchronizers. With events disabled
it reports initialized and a fork does not break it, as LDD mode did.

The diagnostic init event no longer reports customBaseURI,
customStreamURI, pollingIntervalMillis, streamingDisabled or
usingRelayDaemon. The FDv2 fields are still to be decided before 9.0.

The FDv1 fallback that FDv2 uses stays. UnexpectedResponseError moves to
Impl::DataSystem with the FDv2 polling code.
The FDv2 polling builder and the FDv1 fallback polling builder replace
a poll interval below 30 seconds with 30 seconds and log a warning. The
removed poll_interval config option had the same minimum. Without it, a
small or zero interval polls LaunchDarkly in a tight loop.
The polling, streaming and FDv1 fallback sources send the SDK key whatever their base URI, so they need it even when they connect to a Relay Proxy. The old name said that they connect to LaunchDarkly.
- The FDv2 and FDv1 fallback HTTP polling requesters: request headers,
  ETag and 304, gzip, the basis parameter, error status, response
  headers and proxy.
- PollingDataSource#stop ends a long interval wait.
- FileData v2: YAML with a Ruby object and file paths with shell
  metacharacters do not run code, reload without the listen gem, an
  initial sync failure, full flags from flagValues, and evaluation
  through LDClient.
- Every FlagBuilderV2 and FlagRuleBuilderV2 method.
- Streaming sync error paths, and the environment ID through the real
  on_connect handler in place of a copy of its logic.
- The FeatureStoreClientWrapperV2 availability poller.
- FDv2 data availability: CACHED, DEFAULTS and daemon mode.
- StatusProviderV2 listener notifications.
@keelerm84
keelerm84 requested a review from a team as a code owner November 5, 2026 17:43

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant