feat: Add the file-based override source - #367
Draft
kinyoklion wants to merge 1 commit into
Draft
kinyoklion wants to merge 1 commit into
kinyoklion wants to merge 1 commit into
Conversation
Adds FileOverrides.Source() and FileOverrideSourceBuilder with FilePaths, DuplicateKeysHandling (Fail by default, or Ignore), ChangeDetection (Polling by default, or Watching), PollInterval (one second by default and at minimum), and Parser for non-JSON content. The source reads files in the file data document format, expands flagValues entries into flags that are off and serve their single value, merges the files in order, treats a missing file as contributing no overrides, keeps the last good overrides across a file that cannot be read or parsed with a logged failure and a retry, and logs the overrides in effect and what each file supplied at Info level on every applied change, as defined by the OVERRIDE specification.
kinyoklion
force-pushed
the
rlamb/overrides-dotnet-events
branch
from
September 28, 2026 20:39
86caaa5 to
9ddeb28
Compare
kinyoklion
force-pushed
the
rlamb/overrides-dotnet-file-source
branch
from
September 28, 2026 20:39
4011fef to
bf327fc
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
Adds the file-based override source, as defined by the OVERRIDE specification, on top of the shared file loading code and the override layer from the earlier changes in this series. The existing file data source keeps its current behavior: it does not use the shared code, and nothing in this change touches it.
Configuration:
FileOverrides.Source()returns aFileOverrideSourceBuilderthat is passed toDataSystemBuilder.Overrides(...). Its options areFilePaths(one or more files, in precedence order, required),DuplicateKeysHandling(Fail, the default, orIgnore, which keeps the first configured file's entry),ChangeDetection(Polling, the default, orWatching),PollInterval(one second by default and at minimum; a lower value is raised to the minimum with a warning), andParserfor non-JSON content such as YAML. Building a source with no file paths, or with an option outside its enumeration, throws, so the client constructor fails the same way it does for other invalid component configuration. Every public member carries the note that flag overrides are currently experimental and subject to change.Behavior: the files use the file data source document format (
flags,flagValues,segments); aflagValuesentry expands to a flag that is off and serves its single value, so it evaluates with theOFFreason. The initial load runs inside the client constructor. A configured file that does not exist contributes no overrides and produces no error log; creating it later adds its overrides and deleting it removes them. A file that exists but cannot be read or parsed, or a duplicate key underFail, fails that whole reload: the previously loaded overrides stay in effect, the failure is logged, and the source retries after a bounded delay and on the next change. Every applied change is logged at Info level with the overrides in effect and what each configured file supplied (for exampleFlag overrides in effect: 2 flags, 1 segment (/etc/ld/a.json: 2 flags, 1 segment; /etc/ld/b.json: absent)). Polling examines the files' modification time, size, and existence once per interval; watching uses file system notifications on each file's directory.YAML: the SDK does not bundle a YAML parser, following the existing file data source, so YAML files require the application to supply a parser through the
Parseroption. The specification asks for YAML support in the source itself; this is the deliberate deviation for the .NET SDK, and adding a YAML dependency to the SDK package is the alternative.Tests cover the builder validation and defaults, every file behavior above in both change detection modes, the Info log lines, and a client end-to-end scenario in which an operator adds, changes, and removes an override on a running client that never obtains LaunchDarkly data.
This PR is based on the branch of the server events change, which it depends on.