Skip to content
This repository has been archived by the owner on Nov 14, 2024. It is now read-only.

Add metrics for cache instance count #5631

Merged
merged 6 commits into from
Sep 13, 2021
Merged
Show file tree
Hide file tree
Changes from all 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 @@ -106,4 +106,5 @@ private CellFilterMetrics() {
public static final String LW_CACHE_RATIO_USED = "lockWatchCacheRatioUsed";
public static final String LW_EVENT_CACHE_FALLBACK_COUNT = "lockWatchEventCacheFallbackCount";
public static final String LW_VALUE_CACHE_FALLBACK_COUNT = "lockWatchValueCacheFallbackCount";
public static final String LW_TRANSACTION_CACHE_INSTANCE_COUNT = "lockWatchTransactionCacheInstanceCount";
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.palantir.atlasdb.keyvalue.api.cache;

import com.codahale.metrics.Counter;
import com.codahale.metrics.Gauge;
import com.palantir.atlasdb.AtlasDbMetricNames;
import com.palantir.atlasdb.util.CurrentValueMetric;
import com.palantir.atlasdb.util.MetricsManager;
Expand Down Expand Up @@ -112,4 +113,9 @@ public void setMaximumCacheSize(long maximumCacheSize) {
AtlasDbMetricNames.LW_CACHE_RATIO_USED,
() -> () -> cacheSize.getCount() / (double) maximumCacheSize);
}

public void setTransactionCacheInstanceCountGauge(Gauge<Integer> getCacheMapCount) {
metricsManager.registerOrGetGauge(
CacheMetrics.class, AtlasDbMetricNames.LW_TRANSACTION_CACHE_INSTANCE_COUNT, () -> getCacheMapCount);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ final class CacheStoreImpl implements CacheStore {
this.maxCacheCount = maxCacheCount;
this.cacheMap = new ConcurrentHashMap<>();
this.validationProbability = validationProbability;
metrics.setTransactionCacheInstanceCountGauge(cacheMap::size);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,17 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

import com.codahale.metrics.Gauge;
import com.google.common.collect.ImmutableSet;
import com.palantir.atlasdb.keyvalue.api.watch.Sequence;
import com.palantir.atlasdb.keyvalue.api.watch.StartTimestamp;
import com.palantir.atlasdb.transaction.api.TransactionFailedRetriableException;
import io.vavr.collection.HashMap;
import io.vavr.collection.HashSet;
import org.junit.Test;
import org.mockito.ArgumentCaptor;

public final class CacheStoreImplTest {
private static final StartTimestamp TIMESTAMP_1 = StartTimestamp.of(1L);
Expand All @@ -49,6 +52,7 @@ public void updatesToSnapshotStoreReflectedInCacheStore() {
ValueCacheSnapshotImpl.of(HashMap.empty(), HashSet.empty(), ImmutableSet.of()));
cacheStore.createCache(TIMESTAMP_2);
assertThat(cacheStore.getCache(TIMESTAMP_2)).isExactlyInstanceOf(ValidatingTransactionScopedCache.class);
assertThat(getTransactionCacheInstanceCount()).isEqualTo(1);
}

@Test
Expand All @@ -66,6 +70,7 @@ public void multipleCallsToGetReturnsTheSameCache() {
TransactionScopedCache cache2 = cacheStore.getCache(TIMESTAMP_2);

assertThat(cacheStore.getCache(TIMESTAMP_1)).isEqualTo(cache1).isNotEqualTo(cache2);
assertThat(getTransactionCacheInstanceCount()).isEqualTo(2);
}

@Test
Expand All @@ -85,6 +90,7 @@ public void cachesExceedingMaximumCountThrows() {
.isExactlyInstanceOf(TransactionFailedRetriableException.class)
.hasMessage("Exceeded maximum concurrent caches; transaction can be retried, but with caching "
+ "disabled");
assertThat(getTransactionCacheInstanceCount()).isEqualTo(2);
}

@Test
Expand All @@ -99,6 +105,7 @@ public void getCacheDoesNotPersistAnything() {
assertThat(cacheStore.getCache(TIMESTAMP_1)).isExactlyInstanceOf(NoOpTransactionScopedCache.class);
cacheStore.createCache(TIMESTAMP_1);
assertThat(cacheStore.getCache(TIMESTAMP_1)).isExactlyInstanceOf(ValidatingTransactionScopedCache.class);
assertThat(getTransactionCacheInstanceCount()).isEqualTo(1);
}

@Test
Expand All @@ -110,5 +117,13 @@ public void noOpCachesAreNotStored() {
cacheStore.createCache(TIMESTAMP_2);
assertThat(cacheStore.getCache(TIMESTAMP_1)).isExactlyInstanceOf(NoOpTransactionScopedCache.class);
assertThat(cacheStore.getCache(TIMESTAMP_2)).isExactlyInstanceOf(NoOpTransactionScopedCache.class);
assertThat(getTransactionCacheInstanceCount()).isEqualTo(0);
}

@SuppressWarnings("unchecked")
private int getTransactionCacheInstanceCount() {
ArgumentCaptor<Gauge<Integer>> cacheInstanceCount = ArgumentCaptor.forClass(Gauge.class);
verify(metrics).setTransactionCacheInstanceCountGauge(cacheInstanceCount.capture());
return cacheInstanceCount.getValue().getValue();
}
}
5 changes: 5 additions & 0 deletions changelog/@unreleased/pr-5631.v2.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
type: improvement
improvement:
description: Add metric for tracking the count of transaction caches stored in the transaction map, connected to memory leaks such as PDS-185998 and PDS-209612
links:
- https://github.com/palantir/atlasdb/pull/5631