Skip to content

feat: add feature data change notifications - #33

Open
raphaelbrk wants to merge 2 commits into
featbit:mainfrom
raphaelbrk:feat/data-change-notifications
Open

feat: add feature data change notifications#33
raphaelbrk wants to merge 2 commits into
featbit:mainfrom
raphaelbrk:feat/data-change-notifications

Conversation

@raphaelbrk

@raphaelbrk raphaelbrk commented Aug 8, 2026

Copy link
Copy Markdown

Summary

  • Adds an opt-in public notification contract for locally applied FeatBit feature-data updates.
  • Raises notifications after full synchronizations and effective feature-flag or segment patches.
  • Registers the notifier as the same singleton instance as IFbClient and documents safe subscription and disposal.

Validation

  • dotnet test tests/FeatBit.ServerSdk.Tests/FeatBit.ServerSdk.Tests.csproj --no-restore -f net6.0
    • Passed: 179; Skipped: 1.
  • Built the SDK for netstandard2.0, netstandard2.1, netcoreapp3.1, and net6.0.

Post-Deploy Monitoring & Validation

No additional production monitoring is required before adoption because this is an opt-in SDK event and does not change feature evaluation behavior for existing consumers.

For adopters, verify that subscribers receive a notification after a full synchronization or an effective patch, and that a failing subscriber does not prevent the client or other subscribers from continuing. Roll back by removing the subscriber or retaining the previous SDK version if an integration misuses the event.

Greptile Summary

The PR adds opt-in feature-data change notifications and forwards effective full-sync and patch changes through FbClient.

  • Adds the public notification interface, event arguments, and change-kind enum.
  • Marks both data categories as potentially changed after every full replacement.
  • Isolates subscriber exceptions and stops forwarding notifications after client shutdown.
  • Registers the notifier as the same dependency-injection singleton as IFbClient.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
src/FeatBit.ServerSdk/DataSynchronizer/WebSocketDataSynchronizer.cs Publishes notifications after full replacements and effective patches, with full synchronization correctly invalidating both data categories.
src/FeatBit.ServerSdk/FbClient.cs Forwards synchronizer notifications to isolated subscriber callbacks and unsubscribes during shutdown.
src/FeatBit.ServerSdk/DependencyInjection/ServiceCollectionExtensions.cs Resolves the notification contract from the same singleton client instance.
src/FeatBit.ServerSdk/IFbClientDataChangeNotifier.cs Defines the opt-in public event contract and documents callback and startup semantics.
tests/FeatBit.ServerSdk.Tests/DataSynchronizer/WebSocketDataSynchronizerTests.cs Covers full replacement, removal metadata, effective feature-flag and segment patches, and no-op patches.
tests/FeatBit.ServerSdk.Tests/FbClientTests.cs Covers event forwarding, subscriber isolation, startup timing, shutdown from an asynchronous handler, and post-close behavior.

Sequence Diagram

sequenceDiagram
    participant WS as WebSocket
    participant Sync as WebSocketDataSynchronizer
    participant Store as MemoryStore
    participant Client as FbClient
    participant Subscriber
    WS->>Sync: data-sync message
    Sync->>Store: Populate or Upsert
    Store-->>Sync: update applied
    Sync->>Client: DataChanged
    Client->>Subscriber: DataChanged
    Note over Client,Subscriber: Subscriber exceptions are isolated
Loading

Reviews (3): Last reviewed commit: "fix: invalidate full feature data synchr..." | Re-trigger Greptile

Summary by CodeRabbit

  • New Features

    • Added data-change notifications for full synchronizations and effective partial updates.
    • Exposed change details, including update type and whether feature flags or segments may have changed.
    • Added client-level event support for reacting to local feature-data updates.
  • Bug Fixes

    • Avoided notifications when incoming updates do not change stored data.
    • Improved notification handling during startup and shutdown.
  • Tests

    • Added coverage for synchronization events, update filtering, subscriber errors, and lifecycle behavior.

  - expose IFbClientDataChangeNotifier through the server SDK
  - notify subscribers after full and effective patch synchronizations
  - identify whether feature flags or segments were changed
  - register the notifier as the same singleton instance as IFbClient
  - isolate subscriber exceptions and stop forwarding events after shutdown
  - document the subscribe-then-refresh pattern for initial state
  - add coverage for full, patch, segment, DI, and client lifecycle behavior
@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The SDK adds feature-data change contracts and notifications. Synchronizers report full and effective patch updates. FbClient forwards events, manages subscription lifecycle, and exposes the notifier through dependency injection. Tests cover synchronization, startup, shutdown, and handler behavior.

Changes

Feature data change notifications

Layer / File(s) Summary
Change notification contracts
src/FeatBit.ServerSdk/FeatureDataChangeKind.cs, src/FeatBit.ServerSdk/FeatureDataChangedEventArgs.cs, src/FeatBit.ServerSdk/IFbClientDataChangeNotifier.cs, src/FeatBit.ServerSdk/DataSynchronizer/IDataChangeNotifier.cs
Defines full and patch change kinds, immutable event metadata, and notifier event contracts.
Synchronizer notification emission
src/FeatBit.ServerSdk/DataSynchronizer/WebSocketDataSynchronizer.cs, src/FeatBit.ServerSdk/DataSynchronizer/NullDataSynchronizer.cs
Reports full synchronization and effective feature-flag or segment patches. The null synchronizer accepts subscriptions without emitting events.
Client forwarding and DI registration
src/FeatBit.ServerSdk/FbClient.cs, src/FeatBit.ServerSdk/DependencyInjection/ServiceCollectionExtensions.cs
FbClient forwards synchronizer events, isolates subscriber exceptions, and unsubscribes during closure. AddFeatBit resolves the notifier from the registered client.
Behavior validation and test fixtures
tests/FeatBit.ServerSdk.Tests/DataSynchronizer/WebSocketDataSynchronizerTests.cs, tests/FeatBit.ServerSdk.Tests/FbClientTests.cs, tests/FeatBit.ServerSdk.Tests/DependencyInjection/ServiceCollectionExtensionsTests.cs, tests/FeatBit.ServerSdk.Tests/TestData.cs, tests/FeatBit.ServerSdk.Tests/TestStartup.cs
Tests validate notification metadata, ineffective patches, startup refresh, subscriber isolation, shutdown behavior, DI identity, and post-close suppression.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant WebSocketDataSynchronizer
  participant FbClient
  participant DataChangedSubscriber
  WebSocketDataSynchronizer->>FbClient: raise DataChanged
  FbClient->>DataChangedSubscriber: invoke handler with change metadata
  DataChangedSubscriber-->>FbClient: complete or throw
  FbClient->>FbClient: log exceptions and continue
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 4.17% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the primary change: adding feature-data change notifications.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Warning

⚠️ This pull request shows signs of AI-generated slop (ai_padded_prose). It has been flagged by CodeRabbit slop detection and should be reviewed carefully.

Comment thread src/FeatBit.ServerSdk/DataSynchronizer/WebSocketDataSynchronizer.cs Outdated
Comment thread src/FeatBit.ServerSdk/FbClient.cs
@raphaelbrk
raphaelbrk force-pushed the feat/data-change-notifications branch from f47959f to 0a88c0c Compare August 8, 2026 23:56
@deleteLater

Copy link
Copy Markdown
Contributor

related to featbit/featbit#672

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@tests/FeatBit.ServerSdk.Tests/DataSynchronizer/WebSocketDataSynchronizerTests.cs`:
- Around line 187-194: Update the test around
WebSocketDataSynchronizer.StartAsync to track DataChanged with a
TaskCompletionSource, then await a bounded post-processing interval before
asserting the source remains incomplete. Ensure the test observes notifications
raised after initialization and fails when DataChanged is incorrectly triggered,
while preserving the existing startup wait.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 99c7f19b-e3dd-402f-9ba4-73ac60c6be65

📥 Commits

Reviewing files that changed from the base of the PR and between 974e2a7 and 51da3ae.

📒 Files selected for processing (13)
  • src/FeatBit.ServerSdk/DataSynchronizer/IDataChangeNotifier.cs
  • src/FeatBit.ServerSdk/DataSynchronizer/NullDataSynchronizer.cs
  • src/FeatBit.ServerSdk/DataSynchronizer/WebSocketDataSynchronizer.cs
  • src/FeatBit.ServerSdk/DependencyInjection/ServiceCollectionExtensions.cs
  • src/FeatBit.ServerSdk/FbClient.cs
  • src/FeatBit.ServerSdk/FeatureDataChangeKind.cs
  • src/FeatBit.ServerSdk/FeatureDataChangedEventArgs.cs
  • src/FeatBit.ServerSdk/IFbClientDataChangeNotifier.cs
  • tests/FeatBit.ServerSdk.Tests/DataSynchronizer/WebSocketDataSynchronizerTests.cs
  • tests/FeatBit.ServerSdk.Tests/DependencyInjection/ServiceCollectionExtensionsTests.cs
  • tests/FeatBit.ServerSdk.Tests/FbClientTests.cs
  • tests/FeatBit.ServerSdk.Tests/TestData.cs
  • tests/FeatBit.ServerSdk.Tests/TestStartup.cs

Comment on lines +187 to +194
var synchronizer = new WebSocketDataSynchronizer(options, store, op => _app.CreateFbWebSocket(op));
var notified = false;
synchronizer.DataChanged += (_, _) => notified = true;

await synchronizer.StartAsync().WaitAsync(options.StartWaitTime);

Assert.False(notified);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Wait for message processing before asserting notification absence.

StartAsync() completes when initialization completes. The synchronizer calls OnDataChanged after that completion point. Therefore, Line 193 can pass before an incorrect notification runs.

Use a TaskCompletionSource for the event and wait for a bounded post-processing interval before asserting that it did not complete. This test must fail if an ineffective patch raises DataChanged.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@tests/FeatBit.ServerSdk.Tests/DataSynchronizer/WebSocketDataSynchronizerTests.cs`
around lines 187 - 194, Update the test around
WebSocketDataSynchronizer.StartAsync to track DataChanged with a
TaskCompletionSource, then await a bounded post-processing interval before
asserting the source remains incomplete. Ensure the test observes notifications
raised after initialization and fails when DataChanged is incorrectly triggered,
while preserving the existing startup wait.

@deleteLater deleteLater self-assigned this Aug 14, 2026
@deleteLater deleteLater added the enhancement New feature or request label Aug 14, 2026
@deleteLater deleteLater moved this to Backlog in FeatBit Aug 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

3 participants