Skip to content

feat: Expose server-side flag change notifier on Client - #632

Draft
kinyoklion wants to merge 2 commits into
mainfrom
devin/1792710412-server-flag-notifier
Draft

kinyoklion wants to merge 2 commits into
mainfrom
devin/1792710412-server-flag-notifier

Conversation

@kinyoklion

@kinyoklion kinyoklion commented Oct 22, 2026 •

Copy link
Copy Markdown
Member

Summary

The server SDK already had a dependency-aware ChangeNotifier, but applications had no way to reach it. This PR exposes it on Client, adds flag-change-listeners support to the contract test service, and fixes a dependency tracking bug that the new listener tests in sdk-test-harness#514 turned up.

Public API (server SDK only). Adds a new pure virtual to IClient, so any out-of-tree implementation of IClient must now implement it:

virtual IChangeNotifier& FlagNotifier() = 0;   // IChangeNotifier::OnFlagChange(handler) -> unique_ptr<IConnection>
  • IDataSystem gains FlagNotifier(). BackgroundSync and FDv2DataSystem return their existing ChangeNotifier. OfflineSystem and LazyLoad return a new NullChangeNotifier, which accepts handlers but never calls them.

Fix: DependencyTracker never updated existing edges. DependencyMap::Get returns a copy and DependencyMap::Set used emplace, which doesn't overwrite. As a result:

  • A new dependency on an item that already had dependents was dropped, so the new dependent wasn't notified.
  • A removed dependency was never cleared, so the old dependent kept getting notified.

Set now uses insert_or_assign, and UpdateDependencies writes its changes back. The removal path also had the wrong DataKind: it removed (kind_of_dep, key) instead of (kind, key). Unit tests cover all three cases.

Contract tests.

  • Adds the flag-change-listeners capability and the registerFlagChangeListener and unregisterListener commands.
  • ClientEntity keeps one IConnection per listener ID. The connections are declared after client_, so they disconnect before the client is destroyed.
  • The synchronous HTTP POST from ContractTestHook::PostCallback moved into PostJsonCallback so both callers share it.

Verification.

  • harness refactor: Implement FDv2 Wire Format + Payload Parser #514 (v3.2.0-alpha.13) with -run 'flag change listeners': 16/16 pass. Before the tracker fix, 14/16 passed; the failures were "a dependency added by an update is followed afterwards" and "a dependency removed by an update is not followed afterwards".
  • gtest_launchdarkly-cpp-server: 574/574 pass.

Not in scope: flag-value-change-listeners. The server SDK has no value change listener API, so the harness skips those 16 tests.

Link to Devin session: https://app.devin.ai/sessions/3c3618a040a544a895800896137ad1ca
Open in Devin Desktop: https://app.devin.ai/desktop/session/3c3618a040a544a895800896137ad1ca?variant=devin
Requested by: @kinyoklion

SDK-3355

devin-ai-integration Bot and others added 2 commits October 22, 2026 23:15
…pendencies

Co-Authored-By: Ryan Lamb <4955475+kinyoklion@users.noreply.github.com>
Co-Authored-By: Ryan Lamb <4955475+kinyoklion@users.noreply.github.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor

I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".

  • Disable automatic comment, CI, and merge conflict monitoring

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant