zmuxuny opened a new issue, #7170: URL: https://github.com/apache/rocketmq-dashboard/issues/7170
### Before Creating the Bug Report - [x] I have searched the [open issues](https://github.com/apache/rocketmq-dashboard/issues) of this repository and believe that this is not a duplicate. - [x] This is a defect in RocketMQ Studio, not a usage question and not a defect in another Apache RocketMQ repository. - [x] I can reproduce this on the current `master` branch, or I have stated the exact version I am running below. ### Studio Version `rocketmq-studio@127c47b06a268cc74224d5f34c56ec7c36ac0d55`. ### Runtime Environment Linux x86_64; JDK 21.0.12.1 and repository-pinned Spring cache dependencies. The reproduction loads the real `CacheConfig` and Spring caching proxy, with a latch-controlled `SettingsRepository` fixture. No live database or browser integration result is claimed. ### Connected RocketMQ Cluster No RocketMQ cluster is needed for this settings-cache race. ### Build Toolchain Maven 3.9.12, offline local dependency cache. Checkstyle: zero violations. ### Describe the Bug Both `SettingsService.listDataSources` overloads use `@Cacheable`, while successful create/update/delete methods clear the shared `data-sources` cache after returning. A cache miss can capture rows before a write, finish after that write has cleared the cache, and then put its old rows back. The production ConcurrentMap cache has no expiry, so later readers keep receiving that stale inventory until another eviction or process restart. This affects both the full list used by the metrics picker and paged settings inventory: a created source can remain absent, an update can keep its old name/bindings, and a deleted source can reappear. The problem is a late cache publication, not a missing eviction annotation. ### Steps to Reproduce 1. Start with a cold `data-sources` cache and one stored source. 2. Invoke either proxied inventory method on a reader thread. Let the repository capture the old rows, then hold its return with a latch. 3. Complete a proxied create, update or delete on another thread; confirm the repository mutation has committed and the original cache eviction has completed. 4. Release the old repository read and wait for both requests to finish. 5. Read the same inventory again. Repeat for both full and paged methods and all three mutation types. ### What Did You Expect to See? After the successful write and overlapping old read have both finished, subsequent inventory requests should use the committed rows. Normal cache hits and unsuccessful-write behavior should remain intact. ### What Did You See Instead? All six deterministic baseline cases fail on unchanged production code: full/page × create/update/delete. After both threads finish, the next list still returns the old source. The tests report 6 failures, 0 errors, 0 skipped; the failure is the stale-row assertion, not an orchestration timeout. ### Additional Context This differs from #4201, which adds missing invalidation after instance deletion; the reported CRUD paths already invalidate. It also differs from #5605 (cache size/cardinality) and #4048 (key collisions). #2195 is the analogous lifecycle issue in a separate Tencent client cache. A narrow candidate is synchronized cache loading for both overloads with the existing ConcurrentMapCacheManager. Its loader holds the same map-bin monitor that clear waits on, so invalidation cannot finish before an already-started old loader publishes. This may delay completion of a write behind an in-flight inventory database read; that trade-off needs explicit regression coverage. No production fix has been applied yet. MetricsService.queryInstance uses the cached inventory for source selection, but queryByDataSource subsequently reloads that source and checks its binding. This report therefore does not claim that old endpoints or credentials are directly used. The confirmed failure is stale cached selection/inventory; exact error outcomes depend on the following validation. ### Are You Willing to Submit a Pull Request? - [x] Yes, I am willing to submit a pull request. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
