Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ synchronized void replaceScheduledTask(int windows, long interval,
}

@Override
public void snapshot(MetricsRecordBuilder builder, boolean all) {
public synchronized void snapshot(MetricsRecordBuilder builder, boolean all) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need synchronized here? Its super class is not.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have the same question.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ferhui @tomscut Thanks your comment.

SpotBugs module:hadoop-common-project/hadoop-common
  Inconsistent synchronization of org.apache.hadoop.metrics2.lib.MutableRollingAverages.recordValidityMs; locked 66% of time Unsynchronized access at MutableRollingAverages.java:66% of time Unsynchronized access at MutableRollingAverages.java:[line 182]

So consider add synchronized.
Reference code MutableRatesWithAggregation#snapshot, the method to add the synchronized

public class MutableRatesWithAggregation extends MutableMetric {
@OverRide
public synchronized void snapshot(MetricsRecordBuilder rb, boolean all) {
Iterator<WeakReference<ConcurrentMap<String, ThreadSafeSampleStat>>> iter =
weakReferenceQueue.iterator();
...
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure whether the synchronized is needed in here, the rest of part look good to me.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ferhui @tomscut @AlphaGouGe Thanks your comment.
this logic is only called when DataNode JMX get SendPacketDownstreamAvgInfo Metrics,
so there is no concurrency security issue at the moment, no need to add synchronized method.
Update PR.

if (all || changed()) {
for (final Entry<String, LinkedBlockingDeque<SumAndCount>> entry
: averages.entrySet()) {
Expand All @@ -179,8 +179,11 @@ public void snapshot(MetricsRecordBuilder builder, boolean all) {
long totalCount = 0;

for (final SumAndCount sumAndCount : entry.getValue()) {
totalCount += sumAndCount.getCount();
totalSum += sumAndCount.getSum();
if (Time.monotonicNow() - sumAndCount.getSnapshotTimeStamp()
< recordValidityMs) {
totalCount += sumAndCount.getCount();
totalSum += sumAndCount.getSum();
}
}

if (totalCount != 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,16 @@ public void testRemoveStaleRecord() throws Exception {
GenericTestUtils.waitFor(
() -> rollingAverages.getStats(numSamples).size() > 0, 500, 5000);
assertEquals(3, rollingAverages.getStats(numSamples).size());
String json = peerMetrics.dumpSendPacketDownstreamAvgInfoAsJson();
for (String peerAddr : peerAddrList) {
assertThat(json, containsString(peerAddr));
}
/* wait for stale report to be removed */
GenericTestUtils.waitFor(
() -> rollingAverages.getStats(numSamples).isEmpty(), 500, 10000);
assertEquals(0, rollingAverages.getStats(numSamples).size());
json = peerMetrics.dumpSendPacketDownstreamAvgInfoAsJson();
assertEquals("{}", json);

/* dn can report peer metrics normally when it added back to cluster */
for (String peerAddr : peerAddrList) {
Expand All @@ -138,6 +144,10 @@ public void testRemoveStaleRecord() throws Exception {
GenericTestUtils.waitFor(
() -> rollingAverages.getStats(numSamples).size() > 0, 500, 10000);
assertEquals(3, rollingAverages.getStats(numSamples).size());
json = peerMetrics.dumpSendPacketDownstreamAvgInfoAsJson();
for (String peerAddr : peerAddrList) {
assertThat(json, containsString(peerAddr));
}
}

/**
Expand Down