yuqi1129 commented on code in PR #11702:
URL: https://github.com/apache/gravitino/pull/11702#discussion_r3426711754


##########
core/src/main/java/org/apache/gravitino/storage/relational/RelationalEntityStore.java:
##########
@@ -451,4 +456,36 @@ private <E extends Entity & HasIdentifier> void 
batchPopulateRelationCache(
       cache.put(sourceId, identType, relType, entityList);
     }
   }
+
+  /**
+   * Invalidates the {@link 
SupportsRelationOperations.Type#METADATA_OBJECT_ROLE_REL} cache entries
+   * keyed by every securable object of the given role.
+   *
+   * <p>The relation cache is keyed by the metadata object 
(catalog/schema/table/...), while a role
+   * mutation (grant/revoke/override/create) is invalidated from the role 
side. The role-side BFS
+   * invalidation only reaches an object's relation cache entry when the role 
had previously been
+   * cached as that object's binding role; a role that is newly granted access 
to an object was
+   * never cached there, so without this explicit invalidation the stale role 
list is served until
+   * the entry's TTL elapses.
+   */
+  private void invalidateMetadataObjectRoleRelationCache(Entity entity) {
+    if (!(entity instanceof RoleEntity)) {
+      return;
+    }
+    List<SecurableObject> securableObjects = ((RoleEntity) 
entity).securableObjects();
+    if (securableObjects == null || securableObjects.isEmpty()) {
+      return;
+    }
+    String metalake = ((RoleEntity) entity).namespace().level(0);
+    for (SecurableObject securableObject : securableObjects) {
+      // Drop only the relation result entry for this object, not the shared 
reverse index. The
+      // reverse index is shared across all roles bound to the object; a full 
invalidate would
+      // cascade through it and evict the other roles' mappings. The next 
listRolesByObject
+      // re-queries the backend and rebuilds both the entry and the reverse 
index.
+      cache.invalidateRelationEntry(
+          MetadataObjectUtil.toEntityIdent(metalake, securableObject),
+          MetadataObjectUtil.toEntityType(securableObject.type()),
+          SupportsRelationOperations.Type.METADATA_OBJECT_ROLE_REL);

Review Comment:
   Does this problem only exist for `METADATA_OBJECT_ROLE_REL`?



##########
core/src/main/java/org/apache/gravitino/cache/SupportsRelationEntityCache.java:
##########
@@ -56,6 +56,24 @@ <E extends Entity & HasIdentifier> Optional<List<E>> 
getIfPresent(
   boolean invalidate(
       NameIdentifier ident, Entity.EntityType type, 
SupportsRelationOperations.Type relType);
 
+  /**
+   * Invalidates only the cached relation result for the given key, without 
cascading through the
+   * reverse index.
+   *
+   * <p>Unlike {@link #invalidate(NameIdentifier, Entity.EntityType,
+   * SupportsRelationOperations.Type)}, this does not evict the reverse-index 
mappings (which are
+   * shared across entities, e.g. all roles bound to one metadata object) or 
other entities' caches.
+   * Use it when a relation result is known to be stale and the next read must 
re-query the backend,
+   * but the shared reverse index must be preserved.
+   *
+   * @param ident the name identifier
+   * @param type the entity type
+   * @param relType the relation type
+   * @return true if the cache entry was removed
+   */
+  boolean invalidateRelationEntry(

Review Comment:
   Can you try to check whether `invalidateOnKeyChange` can solve the problem?  
I am cautious about the newly added interfaces.



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