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