-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
feat: Implement incremental update protocol with multi-version compatibility #1611
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR implements an incremental update protocol with multi-version compatibility to address protocol rigidity and extensibility issues. The solution separates core thread pool parameters from extended monitoring/alarm parameters, preventing unnecessary client refreshes when non-critical fields change or are renamed.
Key Changes:
- Introduces protocol version 2 with core-only MD5 comparison (v1 remains full MD5 for backward compatibility)
- Implements field adapters in ThreadPoolParameterInfo to handle coreSize/corePoolSize naming variations
- Adds utilities for generating versioned MD5 hashes and extracting core vs. extended parameters
Reviewed Changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| Md5ConfigUtil.java | Extracts client protocol version from request header and passes to comparison logic |
| ConfigCacheService.java | Adds version-aware MD5 comparison using incremental MD5 for v2+ clients |
| ClientWorker.java | Updates client to use protocol version 2 and incremental content generation |
| CacheData.java | Initializes cache with incremental content based on protocol version |
| IncrementalMd5Util.java | Provides versioned MD5 generation and change type detection utilities |
| IncrementalContentUtil.java | Implements core/extended parameter separation and field adapter integration |
| ContentUtil.java | Integrates field adapters for backward-compatible content generation |
| ProtocolRigidityTest.java | Tests field renaming compatibility across protocol versions |
| ExtensibilityTest.java | Verifies extended parameter additions don't trigger unnecessary refreshes |
| ContentUtilTest.java | Validates field adapter behavior with old and new field names |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
starters/threadpool/server/src/main/java/cn/hippo4j/springboot/starter/core/CacheData.java
Outdated
Show resolved
Hide resolved
infra/common/src/test/java/cn/hippo4j/common/toolkit/ExtensibilityTest.java
Outdated
Show resolved
Hide resolved
infra/common/src/test/java/cn/hippo4j/common/toolkit/ContentUtilTest.java
Outdated
Show resolved
Hide resolved
infra/common/src/main/java/cn/hippo4j/common/toolkit/IncrementalContentUtil.java
Outdated
Show resolved
Hide resolved
|
@mingri31164 Please describe your testing process for the submitted code. Also, does your submitted code cover all scenarios? For example, does it support smooth compatibility between different versions such as server 2.0.0 and client 1.5.0? |
|
Hi @magestacks , thank you for the review! Here's a comprehensive overview of my testing approach: 1️⃣ Unit Testing1. ProtocolRigidityTest (5 test cases)Addresses the field renaming issue:
2. ExtensibilityTest (6 test cases)Addresses the extended parameter issue:
3. ContentUtilTest (4 test cases)Validates content generation and field adapters:
4. IncrementalMd5UtilBoundaryTest (10 test cases)Boundary conditions and exception handling:
5. Server Module Tests (in
|
| Scenario | Result |
|---|---|
setContent stores full configuration with MD5 separation |
✅ Full content stored, MD5 on core fields |
| Listener receives complete configuration | ✅ All extended params (executeTimeOut, isAlarm) present |
| MD5 only changes on core parameter change | ✅ Extended param changes don't affect MD5 (v2) |
| Bug scenario: Incremental content vs full content | ✅ Detects pre-fix bug, validates fix |
End-to-end: ServerThreadPoolDynamicRefresh parsing |
✅ Refresh receives all critical extended params |
Critical Fix Validation: Test 4 demonstrates the bug where using
IncrementalContentUtil.getIncrementalContent()for content delivery (pre-fix) causes extended parameters to be null. Post-fix usesContentUtil.getPoolContent()to preserve all fields while MD5 calculation still uses incremental content internally.
2️⃣ Cross-Version Compatibility: Server 2.0.0 + Client 1.5.0
Compatibility Matrix
| Server | Client | Protocol | Result |
|---|---|---|---|
| 2.0.0 (v2) | 1.5.0 (v1) | v1 (full MD5) | ✅ Compatible |
| 2.0.0 (v2) | 2.0.0 (v2) | v2 (incremental) | ✅ Compatible |
| 1.5.0 (v1) | 2.0.0 (v2) | v1 (full MD5) | ✅ Compatible |
How Server 2.0.0 Supports Client 1.5.0:
1. Client 1.5.0 behavior:
- Sends request without
X-Hippo4j-Protocol-Versionheader - Uses old field names (
coreSize/maxSize)
2. Server 2.0.0 detection:
// Md5ConfigUtil.java
private static int getClientVersion(HttpServletRequest request) {
String versionHeader = request.getHeader(PROTOCOL_VERSION_HEADER);
return StringUtil.isNotEmpty(versionHeader) ?
Integer.parseInt(versionHeader) : 1; // ← Defaults to v1
}3. Server adaptation:
// IncrementalMd5Util.java
public static String getVersionedMd5(ThreadPoolParameterInfo config, int clientVersion) {
if (clientVersion >= 2) {
return getCoreMd5(config); // v2 client: incremental
}
return getFullMd5(config); // v1 client: full MD5 ✅
}4. Field name compatibility:
// ThreadPoolParameterInfo.java - Field adapter
public Integer corePoolSizeAdapt() {
return corePoolSize != null ? corePoolSize : coreSize; // Unified handling
}Result: Old v1 clients receive exactly the same behavior as before—zero breaking changes.
3️⃣ Implementation Summary
1. Core Components:
IncrementalContentUtil- DefinesPROTOCOL_VERSION=2, core vs extended parametersIncrementalMd5Util- Version-aware MD5 calculationMd5ConfigUtil- Client version extraction (defaults to 1)ConfigCacheService- Uses versioned MD5 comparisonClientWorker- Adds protocol version headerThreadPoolParameterInfo- Field adapters for compatibility
2. Core Parameters (MD5 included):
tenantId, itemId, tpId, corePoolSize, maximumPoolSize, queueType, capacity, keepAliveTime, rejectedType, allowCoreThreadTimeOut
3. Extended Parameters (MD5 excluded in v2):
executeTimeOut, isAlarm, capacityAlarm, livenessAlarm, activeAlarm, rejectedAlarm, alarmInterval
Problem
Solution
coreSize/corePoolSize)Key Changes
IncrementalContentUtilfor core content extractionIncrementalMd5Utilfor versioned MD5 generationThreadPoolParameterInfo(corePoolSizeAdapt(),maximumPoolSizeAdapt())ConfigCacheServicefor version-aware comparisonX-Hippo4j-Protocol-VersionheaderTest Coverage
ProtocolRigidityTest: 5 scenarios for field renaming compatibilityExtensibilityTest: 6 scenarios for extended parameter additionContentUtilTest: 4 scenarios for field adapter verification