feat: Add file loading code for flag overrides - #449
Draft
kinyoklion wants to merge 1 commit into
Draft
kinyoklion wants to merge 1 commit into
kinyoklion wants to merge 1 commit into
Conversation
This was referenced Sep 25, 2026
Adds `LaunchDarkly::Impl::FileData`, the file reading, parsing, merging, and reloading code that the file-based override source defined by the OVERRIDE specification needs. That source must tolerate a missing file, a file that is being written, and a burst of change notifications, and it must keep the last good data when a reload fails. The module provides: - Document parsing for JSON and YAML with validation that the document and its flags, flagValues, and segments members are objects. - An ordered merge of several documents with duplicate keys handling of fail or ignore, flagValues expansion into off flags that serve the value, model deserialization, and per-document entry counts. - A reloader that serializes reloads, debounces change signals, retains the last good result when a reload fails, retries after a bounded delay, reports each distinct failure once, and can skip byte-identical reloads. A configured file that does not exist can be treated as a file with no content. - A stat-based poller that compares existence, modification time, and size, so a file that appears or disappears is a change. - A watcher that uses rb-inotify on Linux to watch the directory of each file without descending into subdirectories, and the listen gem elsewhere, so a file that does not exist yet is picked up when it appears. It retries when a directory does not exist. The existing FDv1 and FDv2 file data sources are not changed. They keep their own implementation and behavior. A new spec pins the behaviors of those sources that their other specs did not assert, so that they stay as they are while this code exists beside them.
kinyoklion
force-pushed
the
rlamb/overrides-ruby-filedata
branch
from
September 28, 2026 20:36
eb26dd7 to
72d5776
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This is the first of a series that adds flag overrides, as defined by the OVERRIDE specification, to the Ruby server SDK. The existing FDv1 and FDv2 file data sources keep their current behavior: this PR does not change
lib/ldclient-rb/impl/integrations/file_data_source.rb,file_data_source_v2.rb, or their specs, and the override feature is additive throughout the series.The file-based override source must tolerate a missing file, a file that is being written, and a burst of change notifications, and it must keep the last good data when a reload fails. This change adds
LaunchDarkly::Impl::FileData, the file reading, parsing, merging, and reloading code that source needs:flags,flagValues, andsegmentsmembers are objects.failorignore, expansion of eachflagValuesentry into a flag that is off and serves the value (so an evaluation reports the OFF reason kind, as the specification describes), deserialization into the data model classes, and per-document entry counts.rb-inotifyon Linux (a dependency of the optionallistengem) to watch the directory of each file without descending into subdirectories, andlistenelsewhere. It picks up a file that does not exist yet when it appears, and it retries once per second when a directory does not exist. Non-recursive watching matters becauselistenscans the whole tree under a watched directory and fails when a subdirectory cannot be read, as happens for a file in the system temporary directory.A new spec,
spec/integrations/file_data_source_compatibility_spec.rb, pins the behaviors of the existing file data sources that their other specs did not assert (per-file version numbering, keying by the entry's own key, the on-plus-fallthrough expansion offlagValues, no retry of a failed load, log messages, modification-time-only polling, no reaction to a deleted file when polling, the FDv1 poller's reload cadence after a change, and use oflistenwhen it is present), so that they stay as they are while this code exists beside them.Verification: unit specs for the document parser, merge, poller, reloader (including debounce, retry, last-good retention, sequential reloads, and stop), and watcher (including a directory with an unreadable subdirectory and the inotify thread lifecycle), the new compatibility pins, and the unchanged existing file data source specs. Full suite and RuboCop are clean. Each new spec was checked against a deliberate defect in the code it covers, and each compatibility pin against a deliberate change to the existing source it pins.