feat(internal): add flag/segment override layer, overlay store, and change notification diff#408
Draft
kinyoklion wants to merge 3 commits into
Draft
feat(internal): add flag/segment override layer, overlay store, and change notification diff#408kinyoklion wants to merge 3 commits into
kinyoklion wants to merge 3 commits into
Conversation
…hange notification diff
This was referenced Jul 7, 2026
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.
Adds
internal/overrides, the core of the flag-overrides feature (OVERRIDE spec): a runtime-mutable layer of flag and segment definitions that will take precedence over LaunchDarkly data at the store read boundary. Nothing consumes this package yet — FDv2 wiring and the public source API come next — so this PR is the data structures and their semantics in isolation.Layer: thread-safe holder of override entries, replaced wholesale on every update (an update is a full snapshot; entries absent from it are removed). Entries are stored as copies carrying the typed-model override marker, so sources stay marker-agnostic and their retained structs are never mutated; the copies are defensively re-preprocessed since the sink can't know how a source constructed them. An emptiness probe is a single atomic read, keeping a configured-but-unpopulated layer effectively free per evaluation.Overlay: aReadOnlyStorethat merges the layer over a base store — the override entry wins per key onGet(including over deleted-item tombstones),GetAllis the union, and initialization status delegates to the base untouched. Serving overrides from an uninitialized base works because an uninitialized memory store reports not-found rather than erroring.Sink: applies serialized layer replacements and computes which flags to notify. The seed set is every added, removed, or changed override entry — added and removed keys always count, because the marker alone changes what an evaluation reports, and same-key changes compare by serialized form since the layer is rebuilt from scratch each time (pointer or version comparison would notify every retained entry, or nothing). Fan-out then runs through dependency trackers built over both the old and the new merged views, because a replacement can rewire dependencies — e.g. removing a flag override restores the LaunchDarkly definition's prerequisite edges, and dependents of the override's own references only exist in the old view. A base read failure degrades fan-out but never drops the directly changed keys.Depends on go-server-sdk-evaluation carrying the ldmodel override marker (launchdarkly/go-server-sdk-evaluation#57); go.mod points at a pseudo-version of that branch and will be pinned to the released version before merge. Based on #404 (the dependency-tracker consolidation this reuses).
SDK-2655