Skip to content

Commit

Permalink
Fix a race condition in MeterRegistry.getOrCreateMeter() (micrometer-…
Browse files Browse the repository at this point in the history
…metrics#1628)

This commit resolves a race condition between meter addition and
composite meter's children addition via meter-added event listener.

Closes micrometer-metricsgh-1622
  • Loading branch information
izeye authored and shakuzen committed Oct 17, 2019
1 parent dc98341 commit 5c10853
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,6 @@ private Meter getOrCreateMeter(@Nullable DistributionStatisticConfig config,
}

m = builder.apply(mappedId, config);
meterMap = meterMap.plus(mappedId, m);

Id synAssoc = originalId.syntheticAssociation();
if (synAssoc != null) {
Expand All @@ -584,6 +583,7 @@ private Meter getOrCreateMeter(@Nullable DistributionStatisticConfig config,
for (Consumer<Meter> onAdd : meterAddedListeners) {
onAdd.accept(m);
}
meterMap = meterMap.plus(mappedId, m);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import io.micrometer.core.instrument.step.StepMeterRegistry;
import io.micrometer.core.instrument.step.StepRegistryConfig;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.RepeatedTest;
import org.junit.jupiter.api.Test;
import reactor.core.publisher.Flux;
import reactor.core.scheduler.Schedulers;
Expand All @@ -34,6 +35,8 @@
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

Expand Down Expand Up @@ -445,4 +448,31 @@ void stopTrackingMetersThatAreRemoved() {
counting.publish();
assertThat(counting.count(functionCounter)).isEqualTo(1);
}

@RepeatedTest(100)
void meterRegistrationShouldWorkConcurrently() throws InterruptedException {
this.composite.add(this.simple);

String meterName = "test.counter";
String tagName = "test.tag";

int count = 10000;
int tagCount = 100;
ExecutorService executor = Executors.newFixedThreadPool(10);
for (int i = 0; i < count; i++) {
int tagValue = i % tagCount;
executor.execute(() -> {
Counter counter = Counter.builder(meterName).tag(tagName, String.valueOf(tagValue))
.register(this.composite);
counter.increment();
});
}
executor.shutdown();
assertThat(executor.awaitTermination(1L, TimeUnit.SECONDS)).isTrue();
for (int i = 0; i < tagCount; i++) {
assertThat(this.composite.find(meterName).tag(tagName, String.valueOf(i)).counter().count())
.isEqualTo(count / tagCount);
}
}

}

0 comments on commit 5c10853

Please sign in to comment.