This is an automated email from the ASF dual-hosted git repository.

madhan pushed a commit to branch ranger-2.8
in repository https://gitbox.apache.org/repos/asf/ranger.git


The following commit(s) were added to refs/heads/ranger-2.8 by this push:
     new 397920ab6 RANGER-5148: fix redundant role cache update in concurrent 
scenarios (#538)
397920ab6 is described below

commit 397920ab6b253a348aa007e9b1d3c25f556bb022
Author: Gooch <[email protected]>
AuthorDate: Mon Jan 12 14:24:23 2026 +0800

    RANGER-5148: fix redundant role cache update in concurrent scenarios (#538)
    
    Co-authored-by: Madhan Neethiraj <[email protected]>
    (cherry picked from commit 6d6bce47ff30a602256a8b97ebeafcfc5cce0a33)
---
 .../org/apache/ranger/common/RangerRoleCache.java  | 99 +++++++++++-----------
 1 file changed, 48 insertions(+), 51 deletions(-)

diff --git 
a/security-admin/src/main/java/org/apache/ranger/common/RangerRoleCache.java 
b/security-admin/src/main/java/org/apache/ranger/common/RangerRoleCache.java
index 933104a16..08f1c999a 100644
--- a/security-admin/src/main/java/org/apache/ranger/common/RangerRoleCache.java
+++ b/security-admin/src/main/java/org/apache/ranger/common/RangerRoleCache.java
@@ -44,7 +44,7 @@ public class RangerRoleCache {
        private final int           waitTimeInSeconds;
        private final ReentrantLock lock = new ReentrantLock();
 
-       RangerRoleCacheWrapper roleCacheWrapper = null;
+       private final RangerRoleCacheWrapper roleCacheWrapper = new 
RangerRoleCacheWrapper();
 
        public static RangerRoleCache getInstance() {
                if (sInstance == null) {
@@ -64,21 +64,45 @@ private RangerRoleCache() {
        }
 
        public RangerRoles getLatestRangerRoleOrCached(String serviceName, 
RoleDBStore roleDBStore, Long lastKnownRoleVersion, Long rangerRoleVersionInDB) 
throws Exception {
-               final RangerRoles ret;
+               RangerRoles ret = null;
 
                if (lastKnownRoleVersion == null || 
!lastKnownRoleVersion.equals(rangerRoleVersionInDB)) {
-                       roleCacheWrapper = new RangerRoleCacheWrapper();
-                       ret              = 
roleCacheWrapper.getLatestRangerRoles(serviceName, roleDBStore, 
lastKnownRoleVersion, rangerRoleVersionInDB);
-               } else {
-                       ret = null;
+                       ret = roleCacheWrapper.getRoles();
+
+                       if (roleCacheWrapper.getRolesVersion() < 
rangerRoleVersionInDB) {
+                               boolean lockResult = false;
+
+                               try {
+                                       lockResult = 
lock.tryLock(waitTimeInSeconds, TimeUnit.SECONDS);
+
+                                       if (lockResult) {
+                                               if 
(roleCacheWrapper.getRolesVersion() < rangerRoleVersionInDB) {
+                                                       ret = 
roleCacheWrapper.getLatestRangerRoles(serviceName, roleDBStore, 
lastKnownRoleVersion, rangerRoleVersionInDB);
+                                               } else {
+                                                       ret = 
roleCacheWrapper.getRoles();
+                                               }
+                                       } else {
+                                               ret = 
roleCacheWrapper.getRoles();
+
+                                               LOG.error("Could not get lock 
in [{}] seconds, returning cached RangerRoles and wait Queue Length:[{}], roles 
version:[{}]", waitTimeInSeconds, lock.getQueueLength(), (ret != null ? 
ret.getRoleVersion() : -1L));
+                                       }
+                               } catch (InterruptedException exception) {
+                                       Thread.currentThread().interrupt();
+                                       
LOG.error("RangerRoleCache.getLatestRangerRoles:lock got interrupted..", 
exception);
+                               } finally {
+                                       if (lockResult) {
+                                               lock.unlock();
+                                       }
+                               }
+                       }
                }
 
                return ret;
        }
 
        private class RangerRoleCacheWrapper {
-               RangerRoles roles;
-               Long        rolesVersion;
+               volatile RangerRoles roles;
+               volatile Long        rolesVersion;
 
                RangerRoleCacheWrapper() {
                        this.roles        = null;
@@ -94,56 +118,29 @@ public Long getRolesVersion() {
                }
 
                public RangerRoles getLatestRangerRoles(String serviceName, 
RoleDBStore roleDBStore, Long lastKnownRoleVersion, Long rolesVersionInDB) 
throws Exception {
-                       RangerRoles ret        = null;
-                       boolean     lockResult = false;
+                       LOG.debug("==> 
RangerRoleCache.getLatestRangerRoles(ServiceName= {} lastKnownRoleVersion= {} 
rolesVersionInDB= {})", serviceName, lastKnownRoleVersion, rolesVersionInDB);
+
+                       // We are getting all the Roles to be downloaded for 
now. Should do downloades for each service based on what roles are there in the 
policies.
+                       final long            startTimeMs  = 
System.currentTimeMillis();
+                       SearchFilter          searchFilter = null;
+                       final Set<RangerRole> rolesInDB    = new 
HashSet<>(roleDBStore.getRoles(searchFilter));
+                       final long            dbLoadTimeMs = 
System.currentTimeMillis() - startTimeMs;
+                       Date                  updateTime   = new Date();
 
                        if (LOG.isDebugEnabled()) {
-                               LOG.debug("==> 
RangerRoleCache.getLatestRangerRoles(ServiceName= " + serviceName + " 
lastKnownRoleVersion= " + lastKnownRoleVersion + " rolesVersionInDB= " + 
rolesVersionInDB + ")");
+                               LOG.debug("loading Roles from database and it 
took:{} seconds", TimeUnit.MILLISECONDS.toSeconds(dbLoadTimeMs));
                        }
 
-                       try {
-                               lockResult = lock.tryLock(waitTimeInSeconds, 
TimeUnit.SECONDS);
+                       RangerRoles ret = new RangerRoles();
 
-                               if (lockResult) {
-                                       // We are getting all the Roles to be 
downloaded for now. Should do downloades for each service based on what roles 
are there in the policies.
-                                       final long            startTimeMs  = 
System.currentTimeMillis();
-                                       SearchFilter          searchFilter = 
null;
-                                       final Set<RangerRole> rolesInDB    = 
new HashSet<>(roleDBStore.getRoles(searchFilter));
-                                       final long            dbLoadTimeMs = 
System.currentTimeMillis() - startTimeMs;
-                                       Date                  updateTime   = 
new Date();
+                       ret.setRangerRoles(rolesInDB);
+                       ret.setRoleUpdateTime(updateTime);
+                       ret.setRoleVersion(rolesVersionInDB);
 
-                                       if (rolesInDB != null) {
-                                               if (LOG.isDebugEnabled()) {
-                                                       LOG.debug("loading 
Roles from database and it took:" + 
TimeUnit.MILLISECONDS.toSeconds(dbLoadTimeMs) + " seconds");
-                                               }
-                                               ret = new RangerRoles();
-
-                                               ret.setRangerRoles(rolesInDB);
-                                               
ret.setRoleUpdateTime(updateTime);
-                                               
ret.setRoleVersion(rolesVersionInDB);
+                       roles        = ret;
+                       rolesVersion = rolesVersionInDB;
 
-                                               rolesVersion = rolesVersionInDB;
-                                               roles = ret;
-                                       } else {
-                                               LOG.error("Could not get Ranger 
Roles from database ...");
-                                       }
-                               } else {
-                                       if (LOG.isDebugEnabled()) {
-                                               LOG.debug("Could not get lock 
in [" + waitTimeInSeconds + "] seconds, returning cached RangerRoles");
-                                       }
-                                       ret = getRoles();
-                               }
-                       } catch (InterruptedException exception) {
-                               
LOG.error("RangerRoleCache.getLatestRangerRoles:lock got interrupted..", 
exception);
-                       } finally {
-                               if (lockResult) {
-                                       lock.unlock();
-                               }
-                       }
-
-                       if (LOG.isDebugEnabled()) {
-                               LOG.debug("<== 
RangerRoleCache.getLatestRangerRoles(ServiceName= " + serviceName + " 
lastKnownRoleVersion= " + lastKnownRoleVersion + " rolesVersionInDB= " + 
rolesVersionInDB + " RangerRoles= " + ret + ")");
-                       }
+                       LOG.debug("<== 
RangerRoleCache.getLatestRangerRoles(ServiceName= {} lastKnownRoleVersion= {} 
rolesVersionInDB= {} RangerRoles= {})", serviceName, lastKnownRoleVersion, 
rolesVersionInDB, ret);
 
                        return ret;
                }

Reply via email to