perf(swift-sdk): gate SPV progress polling on inequality#3555
Conversation
The 1 Hz progress poller in `PlatformWalletManager` reassigned `@Published spvProgress` and `platformAddressSyncIsSyncing` every tick regardless of whether the values had actually changed. Because `PlatformSpvSyncProgress` was `Sendable` but not `Equatable`, every assignment fired `objectWillChange`, forcing every observing view (sync screens, memory explorer, global indicator) to re-evaluate `body` once per second forever — accreting SwiftUI attribute-graph state and burning CPU long after sync settled. After ~12 hours the example app was sitting at 729 MB / 98% CPU. Adds `Equatable` conformance to `PlatformSpvSubProgress` and `PlatformSpvSyncProgress` and gates each assignment on inequality so identical snapshots are dropped. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThe changes optimize polling behavior by adding Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 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 |
Review GateCommit:
|
|
✅ DashSDKFFI.xcframework built for this PR.
SwiftPM (host the zip at a stable URL, then use): .binaryTarget(
name: "DashSDKFFI",
url: "https://your.cdn.example/DashSDKFFI.xcframework.zip",
checksum: "c9c002c3def410e95ca2f5967d5d53db2bd11d9fb1491d331aaf634f2cadaa78"
)Xcode manual integration:
|
Issue being fixed or feature implemented
After leaving
SwiftExampleApprunning overnight the user observed it sitting at 729 MB memory and 98% CPU. Investigation traced the runaway to the 1 Hz SPV-progress polling task inPlatformWalletManager.The poller reassigned
@Published spvProgressand@Published platformAddressSyncIsSyncingon every tick regardless of whether the values had actually changed. BecausePlatformSpvSyncProgressandPlatformSpvSubProgresswereSendablebut notEquatable, each assignment unconditionally firedobjectWillChange— forcing every observing view (the sync screens, the memory explorer,GlobalSyncIndicator) to re-evaluatebodyonce per second forever. Over ~12 hours that's ~43,200 SwiftUI invalidations; the attribute graph and diffing caches accreted, and the loop re-emitted onto the main thread every second forever, even after sync had long settled.What was done?
Equatableconformance toPlatformSpvSubProgressandPlatformSpvSyncProgress(all members were alreadyEquatable— just synthesised conformance).@Publishedassignments instartProgressPolling()on inequality so identical snapshots no longer republish.The polling loop itself, its cancellation in
deinit, and the FFI calls are unchanged.How Has This Been Tested?
xcodebuild -project SwiftExampleApp/SwiftExampleApp.xcodeproj -scheme SwiftExampleApp -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 16,OS=18.6,arch=arm64' buildsucceeds.platform_wallet_manager_sync_progressstack drop out of the hot path once sync settles.Breaking Changes
None.
Equatableis an additive conformance on public types; existing call sites that didn't compare these structs continue to compile unchanged.Checklist:
Summary by CodeRabbit