You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by rc...@apache.org on 2020/06/10 04:10:37 UTC

[james-project] 01/08: JAMES-3170 Add CachedLatencyMetric, CachedHitMetric, CachedMissMetric and test

This is an automated email from the ASF dual-hosted git repository.

rcordier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit e157e17aaded4e7c931bf9f30de1553a8a31b0aa
Author: duc91 <du...@gmail.com>
AuthorDate: Thu Jun 4 15:54:24 2020 +0700

    JAMES-3170 Add CachedLatencyMetric, CachedHitMetric,CachedMissMetric and test
---
 .../blob/cassandra/cache/CachedBlobStore.java      | 21 +++++++++---
 .../blob/cassandra/cache/CachedBlobStoreTest.java  | 40 +++++++++++++++++++++-
 2 files changed, 56 insertions(+), 5 deletions(-)

diff --git a/server/blob/blob-cassandra/src/main/java/org/apache/james/blob/cassandra/cache/CachedBlobStore.java b/server/blob/blob-cassandra/src/main/java/org/apache/james/blob/cassandra/cache/CachedBlobStore.java
index 45952a8e..d33c52f 100644
--- a/server/blob/blob-cassandra/src/main/java/org/apache/james/blob/cassandra/cache/CachedBlobStore.java
+++ b/server/blob/blob-cassandra/src/main/java/org/apache/james/blob/cassandra/cache/CachedBlobStore.java
@@ -36,6 +36,8 @@ import org.apache.james.blob.api.BlobStore;
 import org.apache.james.blob.api.BucketName;
 import org.apache.james.blob.api.ObjectNotFoundException;
 import org.apache.james.blob.api.ObjectStoreIOException;
+import org.apache.james.metrics.api.Metric;
+import org.apache.james.metrics.api.MetricFactory;
 import org.reactivestreams.Publisher;
 
 import com.google.common.base.Preconditions;
@@ -96,22 +98,32 @@ public class CachedBlobStore implements BlobStore {
             this.firstBytes = firstBytes;
             this.hasMore = hasMore;
         }
-
     }
 
     public static final String BACKEND = "blobStoreBackend";
+    public static final String BLOBSTORE_CACHED_LATENCY_METRIC_NAME = "blobstoreCachedLatency";
+    public static final String BLOBSTORE_CACHED_HIT_COUNT_METRIC_NAME = "blobstoreCachedHit";
+    public static final String BLOBSTORE_CACHED_MISS_COUNT_METRIC_NAME = "blobstoreCachedMiss";
+
+    private final Metric metricRetrieveHitCount;
+    private final Metric metricRetrieveMissCount;
 
     private final BlobStoreCache cache;
     private final BlobStore backend;
     private final Integer sizeThresholdInBytes;
+    private final MetricFactory metricFactory;
 
     @Inject
     public CachedBlobStore(BlobStoreCache cache,
                            @Named(BACKEND) BlobStore backend,
-                           CassandraCacheConfiguration cacheConfiguration) {
+                           CassandraCacheConfiguration cacheConfiguration,
+                           MetricFactory metricFactory) {
         this.cache = cache;
         this.backend = backend;
         this.sizeThresholdInBytes = cacheConfiguration.getSizeThresholdInBytes();
+        this.metricFactory = metricFactory;
+        metricRetrieveHitCount = metricFactory.generate(BLOBSTORE_CACHED_HIT_COUNT_METRIC_NAME);
+        metricRetrieveMissCount = metricFactory.generate(BLOBSTORE_CACHED_MISS_COUNT_METRIC_NAME);
     }
 
     @Override
@@ -237,10 +249,11 @@ public class CachedBlobStore implements BlobStore {
     }
 
     private Mono<byte[]> readFromCache(BlobId blobId) {
-        return Mono.from(cache.read(blobId));
+        return Mono.from(metricFactory.runPublishingTimerMetric(BLOBSTORE_CACHED_LATENCY_METRIC_NAME, cache.read(blobId)))
+            .doOnNext(bytes -> metricRetrieveHitCount.increment());
     }
 
     private Mono<byte[]> readBytesFromBackend(BucketName bucketName, BlobId blobId) {
-        return Mono.from(backend.readBytes(bucketName, blobId));
+        return Mono.from(backend.readBytes(bucketName, blobId)).doOnNext(bytes -> metricRetrieveMissCount.increment());
     }
 }
diff --git a/server/blob/blob-cassandra/src/test/java/org/apache/james/blob/cassandra/cache/CachedBlobStoreTest.java b/server/blob/blob-cassandra/src/test/java/org/apache/james/blob/cassandra/cache/CachedBlobStoreTest.java
index 8da8e61..884f14d 100644
--- a/server/blob/blob-cassandra/src/test/java/org/apache/james/blob/cassandra/cache/CachedBlobStoreTest.java
+++ b/server/blob/blob-cassandra/src/test/java/org/apache/james/blob/cassandra/cache/CachedBlobStoreTest.java
@@ -23,6 +23,8 @@ import static org.apache.james.blob.api.BlobStore.StoragePolicy.LOW_COST;
 import static org.apache.james.blob.api.BlobStore.StoragePolicy.SIZE_BASED;
 import static org.apache.james.blob.api.BucketName.DEFAULT;
 import static org.apache.james.blob.cassandra.cache.BlobStoreCacheContract.EIGHT_KILOBYTES;
+import static org.apache.james.blob.cassandra.cache.CachedBlobStore.BLOBSTORE_CACHED_HIT_COUNT_METRIC_NAME;
+import static org.apache.james.blob.cassandra.cache.CachedBlobStore.BLOBSTORE_CACHED_LATENCY_METRIC_NAME;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatCode;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
@@ -42,6 +44,7 @@ import org.apache.james.blob.api.HashBlobId;
 import org.apache.james.blob.api.ObjectNotFoundException;
 import org.apache.james.blob.cassandra.CassandraBlobModule;
 import org.apache.james.blob.cassandra.CassandraBlobStore;
+import org.apache.james.metrics.tests.RecordingMetricFactory;
 import org.assertj.core.api.SoftAssertions;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -64,6 +67,7 @@ public class CachedBlobStoreTest implements BlobStoreContract {
     private BlobStore testee;
     private BlobStore backend;
     private BlobStoreCache cache;
+    private RecordingMetricFactory metricFactory;
 
     @BeforeEach
     void setUp(CassandraCluster cassandra) {
@@ -73,7 +77,8 @@ public class CachedBlobStoreTest implements BlobStoreContract {
             .timeOut(Duration.ofSeconds(60))
             .build();
         cache = new CassandraBlobStoreCache(cassandra.getConf(), cacheConfig);
-        testee = new CachedBlobStore(cache, backend, cacheConfig);
+        metricFactory = new RecordingMetricFactory();
+        testee = new CachedBlobStore(cache, backend, cacheConfig, metricFactory);
     }
 
     @Override
@@ -274,4 +279,37 @@ public class CachedBlobStoreTest implements BlobStoreContract {
             assertThat(Mono.from(cache.read(blobId)).blockOptional()).isEmpty();
         });
     }
+
+    @Test
+    public void readBlobstoreCachedShouldPublishTimerMetrics() {
+        BlobId blobId = Mono.from(backend.save(DEFAULT_BUCKETNAME, APPROXIMATELY_FIVE_KILOBYTES, SIZE_BASED)).block();
+
+        testee.read(DEFAULT_BUCKETNAME, blobId);
+        testee.read(DEFAULT_BUCKETNAME, blobId);
+
+        assertThat(metricFactory.executionTimesFor(BLOBSTORE_CACHED_LATENCY_METRIC_NAME))
+            .hasSize(2);
+    }
+
+    @Test
+    public void readBlobstoreCachedShouldCountWhenHit() {
+        BlobId blobId = Mono.from(testee.save(DEFAULT_BUCKETNAME, APPROXIMATELY_FIVE_KILOBYTES, SIZE_BASED)).block();
+
+        testee.read(DEFAULT_BUCKETNAME, blobId);
+        testee.read(DEFAULT_BUCKETNAME, blobId);
+
+        assertThat(metricFactory.countFor(BLOBSTORE_CACHED_HIT_COUNT_METRIC_NAME))
+            .isEqualTo(2);
+    }
+
+    @Test
+    public void readBlobstoreCachedShouldCountWhenMissed() {
+        BlobId blobId = Mono.from(testee.save(DEFAULT_BUCKETNAME, APPROXIMATELY_FIVE_KILOBYTES, SIZE_BASED)).block();
+
+        testee.read(DEFAULT_BUCKETNAME, blobId);
+        testee.read(DEFAULT_BUCKETNAME, blobId);
+
+        assertThat(metricFactory.countFor(BLOBSTORE_CACHED_HIT_COUNT_METRIC_NAME))
+            .isEqualTo(2);
+    }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org