sivakumar-mahalingam opened a new issue, #4462:
URL: https://github.com/apache/amoro/issues/4462

   ### What happened?
   
   The AMS overview page periodically refreshes its cached list of top tables. 
This cache is shared between:
   
   1. A background thread that refreshes the cache.
   2. HTTP request threads that read the cache for the 
`/api/ams/v1/overview/top` endpoint.
   
   The cache is currently a regular `ArrayList`, which is not thread-safe. 
During a refresh, AMS first removes every entry and then adds the updated 
entries:
   
   this.allTopTableItem.clear();
   this.allTopTableItem.addAll(topTableItemMap.values());
   
   These are two separate operations. An HTTP request can read the cache after 
`clear()` has completed but before `addAll()` has completed. In that case, the 
API may temporarily return an empty top-table list even though tables exist.
   
   A request may also copy the list while it is being modified. Because the 
read and write operations are not synchronized, this can produce an 
inconsistent result or a runtime exception.
   
   Expected behavior:
   
   Every request should receive a complete cache snapshot—either the snapshot 
from before the refresh or the new snapshot after the refresh.
   
   Actual behavior:
   
   Requests can observe the temporary or partially updated state of the cache 
while a background refresh is running.
   
   This issue is intermittent and depends on the timing of the background 
refresh and incoming HTTP requests.
   
   ### Affects Versions
   
   master
   
   ### What table formats are you seeing the problem on?
   
   Mixed-Hive, Mixed-Iceberg, Paimon, Iceberg
   
   ### What engines are you seeing the problem on?
   
   AMS
   
   ### How to reproduce
   
   This is an intermittent concurrency issue.
   
   1. Start AMS with several registered tables.
   2. Configure a short overview cache refresh interval, for example:
   
      ```
      overview-cache:
        refresh-interval: 1s
      ```
   
   3. Continuously send concurrent requests to:
   
      ```
      GET /api/ams/v1/overview/top?order=asc&orderBy=tableSize&limit=10
      ```
   
   4. Allow the scheduled OverviewManager refresh to run while the requests are 
being processed.
   5. Compare the returned top-table lists across requests.
   
   Because refreshTableCache() calls clear() and addAll() separately on a 
shared ArrayList, a request can run after clear() but before addAll(), or while 
the ArrayList storage is being modified. The response can consequently contain 
an empty or inconsistent top-table list even though registered tables exist.
   
   The race can also be demonstrated with a concurrency test that repeatedly 
invokes OverviewManager.refresh() in one thread while other threads call 
getAllTopTableItem().
   
   ### Relevant log output
   
   ```shell
   No deterministic log output is available because this is a timing-dependent 
race. Depending on timing, the request may return an inconsistent result 
without logging an exception.
   ```
   
   ### Anything else
   
   _No response_
   
   ### Are you willing to submit a PR?
   
   - [x] Yes I am willing to submit a PR!
   
   ### Code of Conduct
   
   - [x] I agree to follow this project's Code of Conduct


-- 
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]

Reply via email to