Repository navigation
feat: Add the file-based override source - #367
Merged
kinyoklion merged 8 commits intoOct 29, 2026
Merged
Conversation
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
kinyoklion
force-pushed
the
rlamb/overrides-dotnet-events
branch
from
October 1, 2026 23:43
9ddeb28 to
75135db
Compare
kinyoklion
force-pushed
the
rlamb/overrides-dotnet-file-source
branch
from
October 1, 2026 23:43
bf327fc to
e30694a
Compare
kinyoklion
force-pushed
the
rlamb/overrides-dotnet-events
branch
from
October 3, 2026 01:34
75135db to
89329c5
Compare
kinyoklion
force-pushed
the
rlamb/overrides-dotnet-file-source
branch
from
October 3, 2026 01:34
e30694a to
4de98c7
Compare
Member
Author
|
bugbot review |
kinyoklion
force-pushed
the
rlamb/overrides-dotnet-events
branch
from
October 3, 2026 01:52
89329c5 to
403d56e
Compare
kinyoklion
force-pushed
the
rlamb/overrides-dotnet-file-source
branch
from
October 3, 2026 01:52
4de98c7 to
57ffcf0
Compare
kinyoklion
force-pushed
the
rlamb/overrides-dotnet-events
branch
from
October 5, 2026 21:55
403d56e to
b085719
Compare
kinyoklion
force-pushed
the
rlamb/overrides-dotnet-file-source
branch
from
October 5, 2026 21:55
57ffcf0 to
c3dbd2d
Compare
kinyoklion
force-pushed
the
rlamb/overrides-dotnet-events
branch
from
October 5, 2026 22:12
b085719 to
2b54c3e
Compare
kinyoklion
force-pushed
the
rlamb/overrides-dotnet-file-source
branch
from
October 5, 2026 22:12
c3dbd2d to
6973a4f
Compare
kinyoklion
force-pushed
the
rlamb/overrides-dotnet-events
branch
from
October 5, 2026 22:28
2b54c3e to
4ec85dc
Compare
kinyoklion
force-pushed
the
rlamb/overrides-dotnet-file-source
branch
from
October 5, 2026 22:28
6973a4f to
78d3e87
Compare
kinyoklion
force-pushed
the
rlamb/overrides-dotnet-events
branch
from
October 5, 2026 23:56
4ec85dc to
368f8fa
Compare
kinyoklion
force-pushed
the
rlamb/overrides-dotnet-file-source
branch
from
October 5, 2026 23:56
78d3e87 to
08c4cf0
Compare
kinyoklion
force-pushed
the
rlamb/overrides-dotnet-events
branch
from
October 13, 2026 21:03
368f8fa to
f12a5f6
Compare
kinyoklion
force-pushed
the
rlamb/overrides-dotnet-file-source
branch
from
October 13, 2026 21:03
08c4cf0 to
c9c756b
Compare
kinyoklion
force-pushed
the
rlamb/overrides-dotnet-events
branch
from
October 13, 2026 22:13
f12a5f6 to
6d2b453
Compare
kinyoklion
force-pushed
the
rlamb/overrides-dotnet-file-source
branch
from
October 13, 2026 22:13
c9c756b to
e0d0597
Compare
Member
Author
|
bugbot review |
kinyoklion
force-pushed
the
rlamb/overrides-dotnet-events
branch
from
October 16, 2026 21:21
6d2b453 to
4e21dce
Compare
kinyoklion
force-pushed
the
rlamb/overrides-dotnet-file-source
branch
from
October 16, 2026 21:21
6bdec5e to
40f4cd0
Compare
kinyoklion
force-pushed
the
rlamb/overrides-dotnet-events
branch
from
October 23, 2026 23:50
4e21dce to
28e15b9
Compare
kinyoklion
force-pushed
the
rlamb/overrides-dotnet-file-source
branch
from
October 23, 2026 23:50
40f4cd0 to
adf57b3
Compare
kinyoklion
force-pushed
the
rlamb/overrides-dotnet-events
branch
from
October 26, 2026 22:46
28e15b9 to
8bd83fe
Compare
kinyoklion
force-pushed
the
rlamb/overrides-dotnet-file-source
branch
from
October 26, 2026 22:46
adf57b3 to
6ea364e
Compare
kinyoklion
force-pushed
the
rlamb/overrides-dotnet-events
branch
from
October 28, 2026 22:35
69a4fcf to
9d0b734
Compare
kinyoklion
force-pushed
the
rlamb/overrides-dotnet-file-source
branch
from
October 28, 2026 22:35
fc4d238 to
865e1fe
Compare
Member
Author
|
bugbot review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit f18639e. Configure here.
kinyoklion
force-pushed
the
rlamb/overrides-dotnet-events
branch
from
October 29, 2026 16:45
9d0b734 to
9259cff
Compare
kinyoklion
force-pushed
the
rlamb/overrides-dotnet-file-source
branch
from
October 29, 2026 16:45
f18639e to
f755f8c
Compare
keelerm84
approved these changes
Oct 29, 2026
kinyoklion
force-pushed
the
rlamb/overrides-dotnet-events
branch
from
October 29, 2026 20:23
9259cff to
19628f5
Compare
kinyoklion
force-pushed
the
rlamb/overrides-dotnet-file-source
branch
from
October 29, 2026 20:23
f755f8c to
cd33ec6
Compare
kinyoklion
force-pushed
the
rlamb/overrides-dotnet-events
branch
from
October 29, 2026 20:39
19628f5 to
7f9e390
Compare
kinyoklion
force-pushed
the
rlamb/overrides-dotnet-file-source
branch
from
October 29, 2026 20:39
cd33ec6 to
7bad1f8
Compare
kinyoklion
force-pushed
the
rlamb/overrides-dotnet-events
branch
from
October 29, 2026 20:53
7f9e390 to
2b8016e
Compare
kinyoklion
force-pushed
the
rlamb/overrides-dotnet-file-source
branch
from
October 29, 2026 20:53
7bad1f8 to
a281c34
Compare
Base automatically changed from
rlamb/overrides-dotnet-events
to
dotnet-server-sdk-v9
October 29, 2026 21:08
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.
… interval above the timer maximum The file override source sets up its change detector before it reads the files, so a change made during the initial load is reported. The builder rejects a polling interval longer than the timer supports when the client is created, instead of failing when the source starts.
…ntries as duplicate keys A path listed more than once would make every entry of that file a duplicate of itself: under the default fail handling the load failed, and under ignore the first listing won by accident. The builder now drops the repeats, keeps the first occurrence in its place in the order, and logs a warning once at build time. This is the behavior the Node SDK has.
The override source builder's Parser method takes the file extension the parser is for. The parser for a file is chosen by its extension; every other file is parsed as JSON. A configured file with a YAML extension and no registered parser is a configuration error reported when the client is created, since it can never load. The source passes the registered parsers to the reloader. The documentation describes the entry rules: a flag or segment is listed under its key, the key property is optional and must match, and the version property is optional.
…t on Windows Windows file names do not distinguish letter case, so the builder's deduplication of the configured paths ignores case there. On the other platforms the two spellings can name different files, so both are kept.
… SDKs A flagValues entry becomes a flag without client-side availability, so AllFlagsState with ClientSideOnly leaves it out even when the flag it overrides is client-side. A full definition with clientSide is the way to override such a flag. A test pins both.
kinyoklion
force-pushed
the
rlamb/overrides-dotnet-file-source
branch
from
October 29, 2026 21:14
a281c34 to
feaf592
Compare
kinyoklion
added a commit
that referenced
this pull request
Oct 29, 2026
…ice (#368) <!-- TERMAG_PR_BODY_BEGIN --> ## Summary Adds the `flag-overrides` capability to the contract test service and the `overrides` block of the SDK configuration it accepts, as described in the test harness service specification. The block's `filePaths`, `duplicateKeysHandling` (`fail` or `ignore`), `changeDetection` (`polling` or `watching`), and `pollIntervalMs` map onto `FileOverrides.Source()` options, and the source is attached to the FDv2 data system builder that the `dataSystem` block configures. The test service registers a YamlDotNet parser for the `.yaml` and `.yml` extensions so the harness's YAML document test can run. The test service also takes an optional port as its first command line argument, defaulting to 8000, so that several test services can run on one machine. It depends on the file-based override source change, #367, which is merged into `dotnet-server-sdk-v9`. [SDK-3248](https://launchdarkly.atlassian.net/browse/SDK-3248) [SDK-3248]: https://launchdarkly.atlassian.net/browse/SDK-3248?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Overview** > Adds **`flag-overrides`** to the contract test service so the harness can exercise file-based flag overrides on the .NET server SDK. > > Harness JSON can now include an **`overrides`** block (`filePaths`, `duplicateKeysHandling`, `changeDetection`, `pollIntervalMs`), which is mapped to **`FileOverrides.Source()`** and attached to the FDv2 **`dataSystem`** builder; **`overrides` without `dataSystem`** fails fast with an **`ArgumentException`**. **YamlDotNet** is added so **`.yaml`/`.yml`** override files parse correctly in conformance tests. > > The test service **`Main`** also accepts an optional **port** argument (default **8000**) so multiple instances can run on one machine. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 477ea95. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> <!-- TERMAG_PR_BODY_END --> <!-- termag: box=i-0575d1c54853058d7 project=projects --> <sub>Opened from termag</sub>
kinyoklion
pushed a commit
that referenced
this pull request
Oct 29, 2026
…ha.1 (#382) 🤖 I have created a release *beep* *boop* --- ## [9.0.0-alpha.1](LaunchDarkly.ServerSdk-v9.0.0-alpha.0...LaunchDarkly.ServerSdk-v9.0.0-alpha.1) (2026-10-29) ### Features * Add a shared file data reloader, poller, and watcher ([#361](#361)) ([4eed241](4eed241)) * Add the file-based override source ([#367](#367)) ([b834131](b834131)) * Add the override marker to the flag and segment models and mark evaluations ([#363](#363)) ([21f666a](21f666a)) * Add the override store, overlay, source interfaces, and data system wiring ([#364](#364)) ([e1748a1](e1748a1)) * Mark evaluation events as override-affected ([#366](#366)) ([7c873a0](7c873a0)) * Split summary counters by overrideAffected and suppress individual events for marked evaluations ([#365](#365)) ([c9b327b](c9b327b)) * Support the flag-overrides capability in the contract test service ([#368](#368)) ([b80d6aa](b80d6aa)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Overview** > This is a **Release Please** cut that publishes **LaunchDarkly.ServerSdk `9.0.0-alpha.1`**. The diff only updates release metadata: `.release-please-manifest.json`, `LaunchDarkly.ServerSdk.csproj` `<Version>`, `PROVENANCE.md` verification example, and a new **`9.0.0-alpha.1`** section in `CHANGELOG.md`. > > The changelog entry documents what ships in this alpha (already merged elsewhere): **local flag overrides** via override store/overlay/source wiring and a **file-based override source** with shared file reloader/poller/watcher; **override markers** on flag/segment models and evaluations; **analytics** changes that mark override-affected evaluations, split summary counters by `overrideAffected`, and suppress individual events when appropriate; plus **contract-test** support for the flag-overrides capability. > > Reviewers can treat this as a **versioning and release-notes sanity check**—no application logic changes appear in the diff itself. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 81f0588. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
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 series targets
dotnet-server-sdk-v9, the branch that prepares the next major version. 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), andParser, which registers a parsing function for a file extension, for formats other than JSON such as YAML. Building a source with no file paths, with an option outside its enumeration, or with a YAML file for which no parser is registered, throws, so the client constructor fails the same way it does for other invalid component configuration. A path listed more than once is logged at Warn and the repeats are ignored; the first occurrence keeps its place in the order. Every public member carries the note that flag overrides are currently experimental and subject to change.Behavior: the files use the file data document format (
flags,flagValues,segments); aflagValuesentry expands to a flag that is on and serves its single value by fallthrough, so it evaluates with theFALLTHROUGHreason. The parser for a file is chosen by its extension, and a file whose extension has no registered parser is parsed as JSON. A flag or segment is listed under its key; akeyproperty in the definition is optional and must be equal to it, and aversionproperty is optional. The initial load runs inside the client constructor. Change detection is in place before the initial load, so a change made between the two is not missed. In watching mode a configured path that is a link to a file in another directory is detected only through the periodic directory check; polling, the default, follows the link directly. 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 register a parser for the
.yamlor.ymlextension through theParseroption. A YAML file configured without one is reported when the client is created, not on every reload. The specification allows the application to supply the parser.Tests cover the builder validation and defaults, including the YAML check, every file behavior above in both change detection modes, the Info log lines, and client end-to-end scenarios in which an operator adds, changes, and removes an override on a running client that never obtains LaunchDarkly data, and in which a YAML override file is read with the registered parser.
It depends on the server events change, #366, which is merged into
dotnet-server-sdk-v9.SDK-3248
Release Please could not parse the squash commit for this PR, so this block supplies its changelog entry:
BEGIN_COMMIT_OVERRIDE
feat: Add the file-based override source (#367)
END_COMMIT_OVERRIDE
Note
Overview
Adds the built-in file override integration so operators can force flag/segment values from local files via
DataSystemBuilder.Overrides(FileOverrides.Source()...), without restarting the client.The public surface is
FileOverrides,FileOverrideSourceBuilder, andFileOverrideTypes(duplicate-key policy, polling vs watching, poll interval, optional per-extension parsers for YAML). The internalFileOverrideSourcemerges multiple paths in order, loads synchronously on startup, hot-reloads through shared file-loading helpers, pushes full snapshots to the override layer, and logs what is in effect per file. Failed reloads keep the last good snapshot; missing files are ignored until they appear.Docs on
DataSystemBuilder.OverridesandIOverrideSourcenow point atFileOverrides. Tests cover builder validation, reload/merge/error behavior, and end-to-endLdClientevaluation (includingOverrideAffectedand client-sideAllFlagsStaterules).Reviewed by Cursor Bugbot for commit feaf592. Bugbot is set up for automated code reviews on this repo. Configure here.
Opened from termag