sunyuhan1998 commented on code in PR #11702:
URL: https://github.com/apache/gravitino/pull/11702#discussion_r3427164142
##########
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:
Good question — it's not unique to `METADATA_OBJECT_ROLE_REL`. I wrote an H2
probe and confirmed `user.roleNames` (`grantRolesToUser` → `ROLE_USER_REL`) and
`group.roleNames` (`grantRolesToGroup` → `ROLE_GROUP_REL`) have the same
defect: an aggregated field mutated via `store.update`, while only the entity
itself is invalidated, so the counterpart-keyed relation cache goes stale when
the freshly granted grantee was never cached against that role.
The latest commit generalizes the helper to all three
(`role.securableObjects`, `user.roleNames`, `group.roleNames`).
`tag`/`policy`/`owner` relations are unaffected — they're written via
`insertRelation`/`updateEntityRelations`, which already invalidate both ends.
--
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]