Repository navigation
feat: Add the file-based override source - #224
kinyoklion wants to merge 5 commits into
Conversation
bd3633b to
e1dd774
Compare
bc2e4a9 to
657a598
Compare
e1dd774 to
752e614
Compare
657a598 to
5be8948
Compare
752e614 to
f76f228
Compare
5be8948 to
9992774
Compare
|
bugbot review |
f76f228 to
b03ecdf
Compare
9992774 to
1728c29
Compare
b03ecdf to
ed4075d
Compare
1728c29 to
c134bcc
Compare
|
bugbot review |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit a0f4c55. Configure here.
| logger.error("Unable to watch override files: {}", LogValues.exceptionSummary(e)); | ||
| logger.debug(LogValues.exceptionTrace(e)); | ||
| } | ||
| break; |
There was a problem hiding this comment.
Watching setup failure stops all reloads
Medium Severity
When WATCHING cannot start, the error is logged and start continues, but neither a watcher nor a poller is left running. After a successful initial load the reloader also has no retry armed, so later file creates, edits, and deletes never apply. That breaks the documented contract that a missing file taking effect later, or an operator updating overrides during an incident, will be picked up.
Reviewed by Cursor Bugbot for commit a0f4c55. Configure here.
The OVERRIDE specification defines a file-based override source that reads override entries from one or more local files and reloads them when the files change. FileOverrides.source() provides it, configured through DataSystemBuilder.overrides(...). The source accepts the file data source document format (flags, flagValues, segments) in JSON or YAML, merges the files in the configured order with the configured duplicate keys handling (fail by default, or ignore all but the first), and keeps the versions that the documents specify. A flagValues entry becomes a flag that is off and serves the value as its single variation. Change detection is polling (the default, one second by default and at minimum) or watching. A configured file that does not exist contributes no overrides. A file that exists but cannot be read or parsed fails that reload, keeps the last good overrides, logs the failure, and is retried. The initial load completes during client construction. Every applied change is logged at Info with the overrides in effect and what each file supplied. Missing file paths, a null change detection mode, or a null poll interval fail client construction. Flag overrides are currently experimental and subject to change.
The poller logs a change callback that throws, so it needs the source's logger. This compiles once the branch includes the poller constructor that takes a logger.
…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.
ed4075d to
c5cfe53
Compare
a0f4c55 to
21f7364
Compare


Summary
This adds the file-based override source that the OVERRIDE specification defines, as
FileOverrides.source()in the integrations package, configured throughDataSystemBuilder.overrides(...):The source reads one or more JSON or YAML files in the file data source document format (
flags,flagValues,segments) in the configured order. AflagValuesentry becomes a flag that is on and serves the value as its single variation by fallthrough, so it evaluates with theFALLTHROUGHreason kind. Entries keep the versions that the documents specify.duplicateKeysHandling:FAIL(the default) fails the reload when the same key appears in more than one file;IGNOREkeeps the entry from the first configured file.changeDetection:POLLING(the default) examines each file's modification time and size on an interval;WATCHINGuses file system notifications. The two are alternatives.pollInterval: one second by default and at minimum; a smaller value is raised to the minimum with a warning.The source is built on
OverrideFileLoader,FileDataReloader,FileDataPoller, andFileDataWatcherfrom the earlier change. The existing file data source keeps its current behavior; this change does not touch its code paths. Flag overrides are currently experimental and subject to change.This PR depends on the override layer and the reload infrastructure changes and is based on the events branch (rlamb/overrides-java-override-events); retarget it to feat/overrides once that branch merges.
SDK-3246
Note
Overview
Adds
FileOverrides.source()as the SDK’s file-basedOverrideSource, wired throughDataSystemBuilder.overrides(...)so operators can load flag/segment overrides from local JSON/YAML (file data document format) during incidents.The builder supports multiple ordered files,
duplicateKeysHandling(FAILvsIGNORE), and reload on change via polling (default 1s, with a minimum) or filesystem watching.FileOverrideSourceImplperforms a synchronous initial load beforestartreturns, pushes full snapshots to the override sink, keeps last-good overrides on parse/read failures (with retry), treats missing files as empty, and logs what’s in effect per file.Docs on
OverrideSourceandDataSystemBuilder#overridesnow point atFileOverrides. A largeFileOverrideSourceTestsuite covers merge order, hot reload, lifecycle, and config validation.Reviewed by Cursor Bugbot for commit a0f4c55. Bugbot is set up for automated code reviews on this repo. Configure here.