Skip to content

Commit

Permalink
HADOOP-11361. Fix a race condition in MetricsSourceAdapter.updateJmxC…
Browse files Browse the repository at this point in the history
…ache. Contributed by Vinayakumar B, Yongjun Zhang, and Brahma Reddy Battula. (ozawa)
  • Loading branch information
oza committed Jul 13, 2016
1 parent 438b7c5 commit 77ffe76
Showing 1 changed file with 14 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

import static com.google.common.base.Preconditions.*;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
Expand Down Expand Up @@ -59,7 +60,6 @@ class MetricsSourceAdapter implements DynamicMBean {
private final MBeanInfoBuilder infoBuilder;
private final Iterable<MetricsTag> injectedTags;

private Iterable<MetricsRecordImpl> lastRecs;
private boolean lastRecsCleared;
private long jmxCacheTS = 0;
private long jmxCacheTTL;
Expand Down Expand Up @@ -175,30 +175,26 @@ private void updateJmxCache() {
}
}

// HADOOP-11361: Release lock here for avoid deadlock between
// MetricsSystemImpl's lock and MetricsSourceAdapter's lock.
Iterable<MetricsRecordImpl> lastRecs = null;
if (getAllMetrics) {
MetricsCollectorImpl builder = new MetricsCollectorImpl();
getMetrics(builder, true);
lastRecs = getMetrics(new MetricsCollectorImpl(), true);
}

synchronized(this) {
updateAttrCache();
if (getAllMetrics) {
updateInfoCache();
synchronized (this) {
if (lastRecs != null) {
updateAttrCache(lastRecs);
updateInfoCache(lastRecs);
}
jmxCacheTS = Time.now();
lastRecs = null; // in case regular interval update is not running
lastRecsCleared = true;
}
}

Iterable<MetricsRecordImpl> getMetrics(MetricsCollectorImpl builder,
boolean all) {
builder.setRecordFilter(recordFilter).setMetricFilter(metricFilter);
synchronized(this) {
if (lastRecs == null && jmxCacheTS == 0) {
all = true; // Get all the metrics to populate the sink caches
}
}
try {
source.getMetrics(builder, all);
} catch (Exception e) {
Expand All @@ -209,10 +205,7 @@ Iterable<MetricsRecordImpl> getMetrics(MetricsCollectorImpl builder,
rb.add(t);
}
}
synchronized(this) {
lastRecs = builder.getRecords();
return lastRecs;
}
return builder.getRecords();
}

synchronized void stop() {
Expand Down Expand Up @@ -246,13 +239,15 @@ long getJmxCacheTTL() {
return jmxCacheTTL;
}

private void updateInfoCache() {
private void updateInfoCache(Iterable<MetricsRecordImpl> lastRecs) {
Preconditions.checkNotNull(lastRecs, "LastRecs should not be null");
LOG.debug("Updating info cache...");
infoCache = infoBuilder.reset(lastRecs).get();
LOG.debug("Done");
}

private int updateAttrCache() {
private int updateAttrCache(Iterable<MetricsRecordImpl> lastRecs) {
Preconditions.checkNotNull(lastRecs, "LastRecs should not be null");
LOG.debug("Updating attr cache...");
int recNo = 0;
int numMetrics = 0;
Expand Down

0 comments on commit 77ffe76

Please sign in to comment.