From def0ac806025905e79cbfea1dfd8a1d7fe80f08e Mon Sep 17 00:00:00 2001 From: Matthew Foley Date: Sun, 19 Feb 2012 22:45:12 +0000 Subject: [PATCH] HADOOP-8050. Deadlock in metrics. Contributed by Kihwal Lee. git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1291084 13f79535-47bb-0310-9956-ffa450edef68 --- .../hadoop-common/CHANGES.txt | 2 + .../metrics2/impl/MetricsSourceAdapter.java | 63 ++++++++++++------- 2 files changed, 43 insertions(+), 22 deletions(-) diff --git a/hadoop-common-project/hadoop-common/CHANGES.txt b/hadoop-common-project/hadoop-common/CHANGES.txt index 15569f5e15d..cbc39e5d740 100644 --- a/hadoop-common-project/hadoop-common/CHANGES.txt +++ b/hadoop-common-project/hadoop-common/CHANGES.txt @@ -212,6 +212,8 @@ Release 0.23.2 - UNRELEASED HADOOP-7680 TestHardLink fails on Mac OS X, when gnu stat is in path. (Milind Bhandarkar via stevel) + HADOOP-8050. Deadlock in metrics. (Kihwal Lee via mattf) + Release 0.23.1 - 2012-02-17 INCOMPATIBLE CHANGES diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/metrics2/impl/MetricsSourceAdapter.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/metrics2/impl/MetricsSourceAdapter.java index 80e4c95c87c..069330001fa 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/metrics2/impl/MetricsSourceAdapter.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/metrics2/impl/MetricsSourceAdapter.java @@ -94,17 +94,19 @@ class MetricsSourceAdapter implements DynamicMBean { } @Override - public synchronized Object getAttribute(String attribute) + public Object getAttribute(String attribute) throws AttributeNotFoundException, MBeanException, ReflectionException { updateJmxCache(); - Attribute a = attrCache.get(attribute); - if (a == null) { - throw new AttributeNotFoundException(attribute +" not found"); + synchronized(this) { + Attribute a = attrCache.get(attribute); + if (a == null) { + throw new AttributeNotFoundException(attribute +" not found"); + } + if (LOG.isDebugEnabled()) { + LOG.debug(attribute +": "+ a); + } + return a.getValue(); } - if (LOG.isDebugEnabled()) { - LOG.debug(attribute +": "+ a); - } - return a.getValue(); } @Override @@ -115,17 +117,19 @@ class MetricsSourceAdapter implements DynamicMBean { } @Override - public synchronized AttributeList getAttributes(String[] attributes) { + public AttributeList getAttributes(String[] attributes) { updateJmxCache(); - AttributeList ret = new AttributeList(); - for (String key : attributes) { - Attribute attr = attrCache.get(key); - if (LOG.isDebugEnabled()) { - LOG.debug(key +": "+ attr); + synchronized(this) { + AttributeList ret = new AttributeList(); + for (String key : attributes) { + Attribute attr = attrCache.get(key); + if (LOG.isDebugEnabled()) { + LOG.debug(key +": "+ attr); + } + ret.add(attr); } - ret.add(attr); + return ret; } - return ret; } @Override @@ -140,17 +144,32 @@ class MetricsSourceAdapter implements DynamicMBean { } @Override - public synchronized MBeanInfo getMBeanInfo() { + public MBeanInfo getMBeanInfo() { updateJmxCache(); return infoCache; } - private synchronized void updateJmxCache() { - if (System.currentTimeMillis() - jmxCacheTS >= jmxCacheTTL) { - if (lastRecs == null) { - MetricsCollectorImpl builder = new MetricsCollectorImpl(); - getMetrics(builder, true); + private void updateJmxCache() { + boolean getAllMetrics = false; + synchronized(this) { + if (System.currentTimeMillis() - jmxCacheTS >= jmxCacheTTL) { + // temporarilly advance the expiry while updating the cache + jmxCacheTS = System.currentTimeMillis() + jmxCacheTTL; + if (lastRecs == null) { + getAllMetrics = true; + } } + else { + return; + } + } + + if (getAllMetrics) { + MetricsCollectorImpl builder = new MetricsCollectorImpl(); + getMetrics(builder, true); + } + + synchronized(this) { int oldCacheSize = attrCache.size(); int newCacheSize = updateAttrCache(); if (oldCacheSize < newCacheSize) {