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

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


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

commit 6d6bce47ff30a602256a8b97ebeafcfc5cce0a33
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]>
---
 .../org/apache/ranger/common/RangerRoleCache.java  | 87 ++++++++++++----------
 1 file changed, 47 insertions(+), 40 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 247a48b46..cbad34b54 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
@@ -43,7 +43,7 @@ public class RangerRoleCache {
     private final int           waitTimeInSeconds;
     private final ReentrantLock lock = new ReentrantLock();
 
-    RangerRoleCacheWrapper roleCacheWrapper;
+    private final RangerRoleCacheWrapper roleCacheWrapper = new 
RangerRoleCacheWrapper();
 
     private RangerRoleCache() {
         RangerAdminConfig config = RangerAdminConfig.getInstance();
@@ -69,21 +69,45 @@ public static RangerRoleCache getInstance() {
     }
 
     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;
@@ -100,45 +124,28 @@ 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);
 
-            try {
-                lockResult = lock.tryLock(waitTimeInSeconds, TimeUnit.SECONDS);
+            // 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 (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();
-
-                    if (LOG.isDebugEnabled()) {
-                        LOG.debug("loading Roles from database and it took:{} 
seconds", TimeUnit.MILLISECONDS.toSeconds(dbLoadTimeMs));
-                    }
-
-                    ret = new RangerRoles();
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("loading Roles from database and it took:{} 
seconds", TimeUnit.MILLISECONDS.toSeconds(dbLoadTimeMs));
+            }
 
-                    ret.setRangerRoles(rolesInDB);
-                    ret.setRoleUpdateTime(updateTime);
-                    ret.setRoleVersion(rolesVersionInDB);
+            ret = new RangerRoles();
 
-                    rolesVersion = rolesVersionInDB;
-                    roles        = ret;
-                } else {
-                    LOG.debug("Could not get lock in [{}] seconds, returning 
cached RangerRoles", waitTimeInSeconds);
+            ret.setRangerRoles(rolesInDB);
+            ret.setRoleUpdateTime(updateTime);
+            ret.setRoleVersion(rolesVersionInDB);
 
-                    ret = getRoles();
-                }
-            } catch (InterruptedException exception) {
-                LOG.error("RangerRoleCache.getLatestRangerRoles:lock got 
interrupted..", exception);
-            } finally {
-                if (lockResult) {
-                    lock.unlock();
-                }
-            }
+            roles        = ret;
+            rolesVersion = rolesVersionInDB;
 
             LOG.debug("<== RangerRoleCache.getLatestRangerRoles(ServiceName= 
{} lastKnownRoleVersion= {} rolesVersionInDB= {} RangerRoles= {})", 
serviceName, lastKnownRoleVersion, rolesVersionInDB, ret);
 

Reply via email to