apache / apache/gravitino

[Bug report] Async cache removal can delete the index entry of a reinserted entity

Open
#13,136 0 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Java
Stars
3.2k
Forks
935
Avg merge
1d 16h
Merged PRs (30d)
298

Description

### Version

main branch

### Describe what is wrong

`CaffeineEntityCache` maintains cached entities in `cacheData` and a hierarchy index in `cacheIndex`. Its removal listener runs asynchronously.

If an old entry is removed and the same key is reinserted before the listener runs, `invalidateExpiredItem()` unconditionally removes the key from `cacheIndex`, even though the new entry still exists in `cacheData`. A subsequent parent-level invalidation cannot discover the child through the index, so the child remains cached.

This race predates #13099 and was identified while reviewing that PR.

### Error message and/or stacktrace

No exception is produced. The failure manifests as divergence between `cacheData` and `cacheIndex`.

### How to reproduce

1. Insert a child entity into the cache.
2. Trigger expiration or eviction of that entry.
3. Reinsert the same key before its asynchronous removal listener executes.
4. Allow the old removal callback to run.
5. Invalidate the parent entity.
6. Observe that the reinserted child remains in `cacheData` because its index entry was removed.

### Additional context

The listener should remove the index entry only when the key is no longer present in `cacheData`, while holding the corresponding segmented lock.

A deterministic regression test should simulate a delayed removal callback followed by reinsertion.

Related: #12377, #13099.

Contributor guide

Open the contributing guide

Research direction

Start by reading CaffeineEntityCache, especially cacheData, cacheIndex, and invalidateExpiredItem(), then locate the existing cache tests. Add a deterministic regression test that delays the removal callback, reinserts the same key, and invalidates its parent; done means the reinserted child is still discoverable and removed by parent invalidation.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.