You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by jo...@apache.org on 2016/03/01 19:30:32 UTC
ambari git commit: AMBARI-15173 - Express Upgrade Stuck At Manual
Prompt Due To HRC Status Calculation Cache Problem (part5) (jonathanhurley)
Repository: ambari
Updated Branches:
refs/heads/trunk 940b2ffe4 -> 97f3089ba
AMBARI-15173 - Express Upgrade Stuck At Manual Prompt Due To HRC Status Calculation Cache Problem (part5) (jonathanhurley)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/97f3089b
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/97f3089b
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/97f3089b
Branch: refs/heads/trunk
Commit: 97f3089badbf4f16f828d92b317bb623605ee66b
Parents: 940b2ff
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Tue Mar 1 12:38:30 2016 -0500
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Tue Mar 1 13:30:21 2016 -0500
----------------------------------------------------------------------
.../server/orm/dao/HostRoleCommandDAO.java | 63 ++++++++++++--------
1 file changed, 37 insertions(+), 26 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/97f3089b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostRoleCommandDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostRoleCommandDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostRoleCommandDAO.java
index 14dac79..b48ffa8 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostRoleCommandDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostRoleCommandDAO.java
@@ -60,8 +60,8 @@ import org.apache.ambari.server.orm.entities.StageEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
@@ -120,8 +120,15 @@ public class HostRoleCommandDAO {
* being read during a transaction which has updated a
* {@link HostRoleCommandEntity}'s {@link HostRoleStatus} but has not
* committed yet.
+ * <p/>
+ * This cache cannot be a {@link LoadingCache} since there is an inherent
+ * problem with concurrency of reloads. Namely, if the entry has been read
+ * during a load, but not yet put into the cache and another invalidation is
+ * registered. The old value would eventually make it into the cache and the
+ * last invalidation would not invalidate anything since the cache was empty
+ * at the time.
*/
- private final LoadingCache<Long, Map<Long, HostRoleCommandStatusSummaryDTO>> hrcStatusSummaryCache;
+ private final Cache<Long, Map<Long, HostRoleCommandStatusSummaryDTO>> hrcStatusSummaryCache;
/**
* Specifies whether caching for {@link HostRoleCommandStatusSummaryDTO} grouped by stage id for requests
@@ -252,24 +259,7 @@ public class HostRoleCommandDAO {
hrcStatusSummaryCache = CacheBuilder.newBuilder()
.maximumSize(hostRoleCommandStatusSummaryCacheLimit)
.expireAfterWrite(hostRoleCommandStatusSummaryCacheExpiryDurationMins, TimeUnit.MINUTES)
- .build(new CacheLoader<Long, Map<Long, HostRoleCommandStatusSummaryDTO>>() {
- @Override
- public Map<Long, HostRoleCommandStatusSummaryDTO> load(Long requestId) throws Exception {
- LOG.debug("Cache miss for host role command status summary object for request {}, fetching from JPA", requestId);
-
- // ensure that we wait for any running transactions working on this cache to
- // complete
- ReadWriteLock lock = transactionLocks.getLock(LockArea.HRC_STATUS_CACHE);
- lock.readLock().lock();
-
- try{
- Map<Long, HostRoleCommandStatusSummaryDTO> hrcCommandStatusByStageId = loadAggregateCounts(requestId);
- return hrcCommandStatusByStageId;
- } finally {
- lock.readLock().unlock();
- }
- }
- });
+ .build();
}
@RequiresSession
@@ -665,16 +655,37 @@ public class HostRoleCommandDAO {
/**
- * Finds the counts of tasks for a request and groups them by stage id.
- * @param requestId the request id
+ * Finds the counts of tasks for a request and groups them by stage id. If
+ * caching is enabled, this will first consult the cache. Cache misses will
+ * then defer to loading the data from the database and then caching the
+ * result.
+ *
+ * @param requestId
+ * the request id
* @return the map of stage-to-summary objects
*/
public Map<Long, HostRoleCommandStatusSummaryDTO> findAggregateCounts(Long requestId) {
- if (hostRoleCommandStatusSummaryCacheEnabled) {
- return hrcStatusSummaryCache.getUnchecked(requestId);
+ if (!hostRoleCommandStatusSummaryCacheEnabled) {
+ return loadAggregateCounts(requestId);
}
- else {
- return loadAggregateCounts(requestId); // if caching not enabled fall back to fetching through JPA
+
+ Map<Long, HostRoleCommandStatusSummaryDTO> map = hrcStatusSummaryCache.getIfPresent(requestId);
+ if (null != map) {
+ return map;
+ }
+
+ // ensure that we wait for any running transactions working on this cache to
+ // complete
+ ReadWriteLock lock = transactionLocks.getLock(LockArea.HRC_STATUS_CACHE);
+ lock.readLock().lock();
+
+ try {
+ map = loadAggregateCounts(requestId);
+ hrcStatusSummaryCache.put(requestId, map);
+
+ return map;
+ } finally {
+ lock.readLock().unlock();
}
}