fix: avoid accidentally deleting new appNamespaceCache of same appid and name with old appNamesppace.#5504
Conversation
…and name with the old appNamespaceCache. Fixes apolloconfig#5502
|
CLA Assistant Lite bot All contributors have signed the CLA ✍️ ✅ |
WalkthroughThis PR fixes a race condition in AppNamespaceServiceWithCache where rapid deletion and recreation of an AppNamespace with identical name and appid could cause unintended cache deletion. The fix adds ID verification during cache removal to ensure only the correct entry is deleted, preventing accidental data loss. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Tip 📝 Customizable high-level summaries are now available in beta!You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.
Example instruction:
Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later. 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: 0
🧹 Nitpick comments (1)
apollo-configservice/src/main/java/com/ctrip/framework/apollo/configservice/service/AppNamespaceServiceWithCache.java (1)
40-40: Wildcardjava.util.*import is functionally fine but may diverge from existing styleSwitching to
java.util.*bringsObjectsinto scope and works, but if the project convention prefers explicit imports, consider importingjava.util.Objectsinstead and keeping the previous specificjava.utilimports for consistency.-import java.util.*; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Objects;
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
CHANGES.md(1 hunks)apollo-configservice/src/main/java/com/ctrip/framework/apollo/configservice/service/AppNamespaceServiceWithCache.java(2 hunks)apollo-configservice/src/test/java/com/ctrip/framework/apollo/configservice/service/AppNamespaceServiceWithCacheTest.java(2 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: nobodyiam
Repo: apolloconfig/apollo PR: 5228
File: apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/NamespaceService.java:356-363
Timestamp: 2024-10-01T07:29:12.146Z
Learning: In the `NamespaceService#save` method, implementing a soft limit for namespace counts is acceptable, even if there may be potential race conditions due to concurrent access.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build (8)
🔇 Additional comments (4)
CHANGES.md (1)
25-25: Changelog entry correctly captures the bugfixThe description and linked issue match the behavior this PR addresses; this is a good, minimal update to the 2.5.0 notes.
apollo-configservice/src/main/java/com/ctrip/framework/apollo/configservice/service/AppNamespaceServiceWithCache.java (1)
262-266: Deleted-cache handling now correctly avoids removing a newly recreated namespaceThe additional check against
appNamespace.getId()ensures you only evict fromappNamespaceCachewhen the cached entry actually corresponds to thedeletedId. This closes the race where a deleted AppNamespace’s cleanup could remove the cache entry for a newly created AppNamespace with the sameappIdandnamespaceName, while still correctly cleaning up genuinely deleted entries.apollo-configservice/src/test/java/com/ctrip/framework/apollo/configservice/service/AppNamespaceServiceWithCacheTest.java (2)
41-41: Static importanyListis appropriate for the new mocking logicThe static import for
anyListis used cleanly in the new stubbing offindAllByIdand keeps the test setup concise.
315-364: New regression test accurately captures and guards against the cache-deletion bug
doubleCheckForAppNamespaceCachecarefully walks through the sequence: load old namespace (id=1), load new namespace (id=2) with the sameappIdandnamespaceName, then invokeupdateAndDeleteCacheand assert that the cache still points to id=2. UsinginvokePrivateMethodto reachscanNewAppNamespacesandupdateAndDeleteCachekeeps the test focused on cache behavior without altering the production API and provides solid protection against regressions of issue #5502.
|
I have read the CLA Document and I hereby sign the CLA |
What's the purpose of this PR
This PR addresses a cache eviction bug in AppNamespaceServiceWithCache that occurs when an AppNamespace is deleted and immediately recreated.
The Problem: When an administrator deletes an AppNamespace and recreates it with the same name and appid within a short window (e.g. 1 minute), the scheduled cleanup task (running every 60s) for the old deleted namespace mistakenly removes the cache key associated with the new namespace. This happens because the cache key is derived from appId + namespaceName, leading to a collision.

The Fix: Updated the cache cleanup logic to ensure that the cache is only evicted if it truly belongs to the deleted namespace, preventing accidental deletion of the new namespace's cache.
Which issue(s) this PR fixes:
Fixes #5502
Brief changelog
Fix: Resolve an issue where the cache of a newly created AppNamespace could be accidentally deleted by the cleanup task of a deleted AppNamespace with the same name and appid.
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.