SotwConfigSourceSubscriptionFactory is a SnapshotStream of DiscoveryResponse#6795
SotwConfigSourceSubscriptionFactory is a SnapshotStream of DiscoveryResponse#6795jrhee17 wants to merge 3 commits into
SotwConfigSourceSubscriptionFactory is a SnapshotStream of DiscoveryResponse#6795Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughMigrates xDS from callback-driven ResourceWatcher/ConfigSourceSubscription to a snapshot-stream model with RefCountedStream lifecycle, ParsedResources holders (SOTW/Delta), interest publishing (InterestedResources), CompositeSnapshotWatcher fanout, and corresponding wiring in factories, manager, and tests. ChangesxDS Snapshot Stream Migration
🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs:
Suggested reviewers:
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 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 `@xds/src/main/java/com/linecorp/armeria/xds/CompositeSnapshotWatcher.java`:
- Around line 79-90: The onUpdate method in CompositeSnapshotWatcher can throw
ConcurrentModificationException if a watcher’s onUpdate() synchronously calls
addWatcher() or removeWatcher(); fix by iterating over a snapshot copy of the
watchers collection instead of the original. In
CompositeSnapshotWatcher.onUpdate, call maybeCancelAbsentTimer() as before, then
make a defensive copy (e.g., new ArrayList<>(watchers)) and iterate that copy
when invoking each watcher.onUpdate(value, error); keep the existing try/catch
and logging and ensure addWatcher/removeWatcher semantics remain unchanged.
In `@xds/src/main/java/com/linecorp/armeria/xds/ConfigSourceHandler.java`:
- Around line 59-85: The current apply(...) methods call stateCoordinator
methods unconditionally and can mutate state on NACKed ParsedResources; before
applying updates or marking missing resources, guard with the ParsedResources
acceptance flag (e.g., check parsed.isAccepted() or parsed.accepted()) so that
apply(ParsedResources.SotwParsedResources),
apply(ParsedResources.DeltaParsedResources) and
applyUpdatesAndErrors(ParsedResources) only invoke
stateCoordinator.onResourceUpdated(...) and
stateCoordinator.onResourceMissing(...) when the parsed snapshot is accepted;
for rejected snapshots, skip updates/missing notifications (you may still
surface errors from parsed.invalidResources() differently if desired) so the
last accepted config remains unchanged.
In `@xds/src/test/java/com/linecorp/armeria/xds/StateCoordinatorTest.java`:
- Around line 100-125: The test currently never seeds the coordinator cache, so
onResourceMissing() doesn't exercise eviction; before calling
coordinator.onResourceMissing(XdsType.CLUSTER, CLUSTER_NAME) add a call to
populate the state (e.g. call coordinator.onResourceUpdated(XdsType.CLUSTER,
CLUSTER_NAME, /* a non-null XdsResource snapshot */) or use the existing
register + an explicit update path) so the resource exists in StateCoordinator's
stateStore, then call onResourceMissing, unregister, and re-register the new
watcher to assert no replay; ensure you reference
StateCoordinator.onResourceUpdated, StateCoordinator.onResourceMissing,
register/unregister, XdsType.CLUSTER and CLUSTER_NAME when making the change.
🪄 Autofix (Beta)
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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 89ce7eb7-ebfd-487d-b681-8b19c3ef8d3e
📒 Files selected for processing (29)
xds/src/main/java/com/linecorp/armeria/xds/AdsXdsStream.javaxds/src/main/java/com/linecorp/armeria/xds/CompositeSnapshotWatcher.javaxds/src/main/java/com/linecorp/armeria/xds/CompositeXdsStream.javaxds/src/main/java/com/linecorp/armeria/xds/ConfigSourceHandler.javaxds/src/main/java/com/linecorp/armeria/xds/ConfigSourceSubscription.javaxds/src/main/java/com/linecorp/armeria/xds/ControlPlaneClientManager.javaxds/src/main/java/com/linecorp/armeria/xds/DeltaActualStream.javaxds/src/main/java/com/linecorp/armeria/xds/GrpcConfigSourceStreamFactory.javaxds/src/main/java/com/linecorp/armeria/xds/InterestPublisher.javaxds/src/main/java/com/linecorp/armeria/xds/ParsedResources.javaxds/src/main/java/com/linecorp/armeria/xds/PathSotwConfigSourceSubscriptionFactory.javaxds/src/main/java/com/linecorp/armeria/xds/ResourceNode.javaxds/src/main/java/com/linecorp/armeria/xds/ResourceNodeAdapter.javaxds/src/main/java/com/linecorp/armeria/xds/ResourceParser.javaxds/src/main/java/com/linecorp/armeria/xds/ResourceWatcher.javaxds/src/main/java/com/linecorp/armeria/xds/SotwActualStream.javaxds/src/main/java/com/linecorp/armeria/xds/SotwConfigSourceSubscriptionFactory.javaxds/src/main/java/com/linecorp/armeria/xds/SotwSubscriptionCallbacks.javaxds/src/main/java/com/linecorp/armeria/xds/StateCoordinator.javaxds/src/main/java/com/linecorp/armeria/xds/SubscriberStorage.javaxds/src/main/java/com/linecorp/armeria/xds/XdsBootstrapImpl.javaxds/src/main/java/com/linecorp/armeria/xds/XdsExtensionRegistry.javaxds/src/main/java/com/linecorp/armeria/xds/XdsStream.javaxds/src/main/java/com/linecorp/armeria/xds/XdsStreamSubscriber.javaxds/src/main/java/com/linecorp/armeria/xds/configsource/InterestedResources.javaxds/src/main/java/com/linecorp/armeria/xds/configsource/SotwConfigSourceSubscriptionFactory.javaxds/src/main/java/com/linecorp/armeria/xds/configsource/package-info.javaxds/src/test/java/com/linecorp/armeria/xds/StateCoordinatorTest.javaxds/src/test/java/com/linecorp/armeria/xds/SubscriberStorageTest.java
💤 Files with no reviewable changes (5)
- xds/src/main/java/com/linecorp/armeria/xds/SotwSubscriptionCallbacks.java
- xds/src/main/java/com/linecorp/armeria/xds/SotwConfigSourceSubscriptionFactory.java
- xds/src/main/java/com/linecorp/armeria/xds/ConfigSourceSubscription.java
- xds/src/main/java/com/linecorp/armeria/xds/ResourceWatcher.java
- xds/src/main/java/com/linecorp/armeria/xds/XdsStreamSubscriber.java
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #6795 +/- ##
============================================
+ Coverage 74.46% 74.99% +0.53%
- Complexity 22234 24942 +2708
============================================
Files 1963 2216 +253
Lines 82437 92703 +10266
Branches 10764 12107 +1343
============================================
+ Hits 61385 69521 +8136
- Misses 15918 17396 +1478
- Partials 5134 5786 +652 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
#6796 should be reviewed before this PR
The changes for this PR is a subset of #6781
Motivation:
The existing
SotwConfigSourceSubscriptionFactorySPI requires implementors to manage threading, interest tracking, and response parsing via callbacks (SotwSubscriptionCallbacks,ConfigSourceSubscription). This makes custom config source implementations (file-based, KV-store-backed, etc.) unnecessarily complex.This PR reshapes the factory into a reactive stream-based API where
create()simply returns aSnapshotStream<DiscoveryResponse>— making custom implementations straightforward:Modifications:
configsource.SotwConfigSourceSubscriptionFactory— new public factory interface returningSnapshotStream<DiscoveryResponse>configsource.InterestedResources— value type representing currently subscribed resource names, delivered as aSnapshotStreamInterestPublisher— stream-based replacement for theupdateInterestscallbackCompositeSnapshotWatcher— fan-out adapter for notifying multipleSnapshotWatchersParsedResourcesHoldertoParsedResourceswithSotwParsedResources/DeltaParsedResourcessubtypesConfigSourceHandlerto subscribe toSnapshotStream<DiscoveryResponse>instead of receiving callbacksGrpcConfigSourceStreamFactory.create()to return aConfigSourceHandlerwired via streamsResourceNode/ResourceNodeAdapter/SubscriberStorage/StateCoordinatorto useSnapshotWatcherinstead ofResourceWatcherdefaultWatchertoControlPlaneClientManagerfor error propagation on stream failuresResourceWatcher,XdsStreamSubscriber,ConfigSourceSubscription,SotwSubscriptionCallbacks, and the old package-privateSotwConfigSourceSubscriptionFactoryResult:
SnapshotStream<DiscoveryResponse>— Armeria handles parsing, storage, and subscriber notification