Skip to content

feat:support rate-limit window expiration.#672

Open
SkyeBeFreeman wants to merge 4 commits into
polarismesh:mainfrom
SkyeBeFreeman:m/ratelimit-expire
Open

feat:support rate-limit window expiration.#672
SkyeBeFreeman wants to merge 4 commits into
polarismesh:mainfrom
SkyeBeFreeman:m/ratelimit-expire

Conversation

@SkyeBeFreeman
Copy link
Copy Markdown
Member

@SkyeBeFreeman SkyeBeFreeman commented Dec 8, 2025

fixes #657

@codecov
Copy link
Copy Markdown

codecov Bot commented Dec 8, 2025

Codecov Report

❌ Patch coverage is 48.68914% with 137 lines in your changes missing coverage. Please review.
✅ Project coverage is 22.89%. Comparing base (7ec8941) to head (9907382).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
.../polaris/ratelimit/client/flow/StreamResource.java 44.73% 36 Missing and 6 partials ⚠️
...polaris/ratelimit/client/flow/WindowContainer.java 33.33% 18 Missing and 2 partials ⚠️
...aris/ratelimit/client/flow/RateLimitExtension.java 57.77% 16 Missing and 3 partials ⚠️
...aris/ratelimit/client/flow/RateLimitWindowSet.java 55.26% 9 Missing and 8 partials ⚠️
...polaris/ratelimit/client/flow/RateLimitWindow.java 70.00% 8 Missing and 1 partial ⚠️
...ncent/polaris/ratelimit/client/flow/QuotaFlow.java 0.00% 8 Missing ⚠️
...om/tencent/polaris/api/plugin/route/RouteInfo.java 0.00% 6 Missing ⚠️
...s/ratelimit/client/sync/PolarisRemoteSyncTask.java 0.00% 5 Missing ⚠️
...s/plugin/location/cloud/CloudLocationProvider.java 42.85% 2 Missing and 2 partials ⚠️
...olaris/ratelimit/client/flow/StreamCounterSet.java 55.55% 3 Missing and 1 partial ⚠️
... and 2 more
Additional details and impacted files
@@             Coverage Diff              @@
##               main     #672      +/-   ##
============================================
+ Coverage     21.59%   22.89%   +1.29%     
- Complexity     1215     1301      +86     
============================================
  Files           417      417              
  Lines         17649    17872     +223     
  Branches       2280     2311      +31     
============================================
+ Hits           3812     4092     +280     
+ Misses        13406    13301     -105     
- Partials        431      479      +48     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

SkyeBeFreeman and others added 2 commits May 14, 2026 20:46
Signed-off-by: Haotian Zhang <928016560@qq.com>
…rt conflict

- Add StreamResourceTest to reproduce the bug where counters.putIfAbsent
  fails to replace old DurationBaseCallback after rule revision update,
  causing server quota responses to be routed to stale windows
- Fix WindowExpireAndRecoverTest port conflict in CI by using dynamic
  port allocation (-1) instead of hardcoded port 10097
- Add debug-level diagnostic logs for rate limit quota synchronization,
  local usage reporting, mode degradation and period boundary reset

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Haotian Zhang <928016560@qq.com>
…piration

Concurrency fixes:
- AsyncRateLimitConnector: stop overwriting uniqueKey parameter; use streamCounterSet.getNode() when removing from nodeToStream after host switch; switch nodeToStream/uniqueKeyToStream to ConcurrentHashMap since peekStreamCounterSet is called from sync thread
- RateLimitExtension.submitSyncTask: replace containsKey+put with atomic computeIfAbsent and stop resetting window status on duplicate (prevents init-state-machine corruption)
- RateLimitExtension.submitExpireJob: null out expireFuture before reschedule to avoid stale reference if scheduleWithFixedDelay throws RejectedExecutionException
- RateLimitExtension.stopSyncTask: skip cleanTask when syncExecutor.isShutdown() instead of inlining; add peekStreamCounterSet to avoid creating a stream during cleanup
- RateLimitWindowSet: short-circuit on expired container in getRateLimitWindow; cleanupContainers/deleteRules use compute for atomic predicate+remove; markExpired before unInit so concurrent reads see DELETED via expired-container short-circuit
- StreamResource.handleRateLimitInitResponse: replace putIfAbsent+put with counters.compute (decision and write under one bin lock); status guard now allows both INITIALIZING and INITIALIZED so redoInit responses are not dropped
- WindowContainer: AtomicBoolean expired flag set before unInit in checkAndCleanExpiredWindows
- RateLimitWindow.unInit: also stopSyncTask for TSF cluster (was skipped due to LOCAL_MODE check)

Tests:
- StreamResourceTest: counterKey reuse across rule revisions, DELETED window drops response, redoInit accepted in INITIALIZED, hasInit threshold
- AsyncRateLimitConnectorTest: uniqueKey overwrite, nodeToStream remove key, peek does not create
- RateLimitExtensionStopSyncTaskTest: no stream creation when stream already gone, duplicate submitSyncTask does not reset status nor schedule new
- RateLimitWindowSetTest: cleanup vs concurrent add race, getRateLimitWindow expired short-circuit, addLabelToRevision atomicity
- RateLimitWindowTsfUnInitTest: TSF window must stop sync task on unInit
- SubmitPolarisRemoteSyncTaskTest: drop obsolete duplicate-submit assertion (covered by client-module test)

Misc:
- @justfortest constructors on RateLimitWindow / StreamResource for unit tests bypassing heavy gRPC / quota-bucket init
- unInit javadoc declares container-must-be-marked-expired contract
- WindowContainer.checkAndCleanExpiredWindows javadoc clarifies return semantics for mainWindow vs regexSpread modes
- AsyncRateLimitConnector class javadoc updated to reflect concurrent access pattern
- StreamResource.hasInit log no longer dumps full initRecord at WARN; debug shows full map
- StreamResource.handleRateLimitInitResponse: LOG.warn moved out of compute lambda to keep bin-lock critical section short
- RateLimitConstants: add STOP_SYNC_CLEAN_DELAY_MS, WINDOW_INDEX_EXPIRE_TIME; restore INIT_WAIT_RESPONSE_TIME literal
- Remove unused imports (ServiceRouterConfig, ArrayList) and dead helper mockExpiredWindow

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Haotian Zhang <928016560@qq.com>
Signed-off-by: Haotian Zhang <928016560@qq.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

优化本地限流窗口过期机制

1 participant