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 bt...@apache.org on 2020/06/19 11:03:49 UTC

[james-project] 01/06: JAMES-3170: Add metric latency for BackEnd in CachedBlobStore

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

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

commit 46e6f64a0f73a4616eab2c1b566b49182120cd4c
Author: duc91 <du...@gmail.com>
AuthorDate: Wed Jun 10 15:40:54 2020 +0700

    JAMES-3170: Add metric latency for BackEnd in CachedBlobStore
---
 .../blob/cassandra/cache/CachedBlobStore.java      | 14 +++---
 .../blob/cassandra/cache/CachedBlobStoreTest.java  | 50 +++++++++++++++++-----
 2 files changed, 49 insertions(+), 15 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 9acbbed..1a14773 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
@@ -103,8 +103,10 @@ public class CachedBlobStore implements BlobStore {
 
     public static final String BACKEND = "blobStoreBackend";
 
-    public static final String BLOBSTORE_CACHED_MISS_COUNT_METRIC_NAME = "blobStoreCacheMisses";
     public static final String BLOBSTORE_CACHED_LATENCY_METRIC_NAME = "blobStoreCacheLatency";
+    public static final String BLOBSTORE_BACKEND_LATENCY_METRIC_NAME = "blobStoreBackEndLatency";
+
+    public static final String BLOBSTORE_CACHED_MISS_COUNT_METRIC_NAME = "blobStoreCacheMisses";
     public static final String BLOBSTORE_CACHED_HIT_COUNT_METRIC_NAME = "blobStoreCacheHits";
 
     private final MetricFactory metricFactory;
@@ -154,12 +156,12 @@ public class CachedBlobStore implements BlobStore {
         return Mono.just(bucketName)
             .filter(getDefaultBucketName()::equals)
             .flatMap(deleteBucket -> readBytesInDefaultBucket(bucketName, blobId))
-            .switchIfEmpty(readBytesFromBackend(bucketName, blobId));
+            .switchIfEmpty(Mono.defer(() -> readBytesFromBackend(bucketName, blobId)));
     }
 
     private Mono<byte[]> readBytesInDefaultBucket(BucketName bucketName, BlobId blobId) {
         return readFromCache(blobId)
-            .switchIfEmpty(readBytesFromBackend(bucketName, blobId)
+            .switchIfEmpty(Mono.defer(() -> readBytesFromBackend(bucketName, blobId))
                 .filter(this::isAbleToCache)
                 .doOnNext(any -> metricRetrieveMissCount.increment())
                 .flatMap(bytes -> saveInCache(blobId, bytes).then(Mono.just(bytes))));
@@ -264,10 +266,12 @@ public class CachedBlobStore implements BlobStore {
     }
 
     private Mono<InputStream> readFromBackend(BucketName bucketName, BlobId blobId) {
-        return Mono.fromCallable(() -> backend.read(bucketName, blobId));
+        return Mono.from(metricFactory.runPublishingTimerMetric(BLOBSTORE_BACKEND_LATENCY_METRIC_NAME,
+            Mono.fromCallable(() -> backend.read(bucketName, blobId))));
     }
 
     private Mono<byte[]> readBytesFromBackend(BucketName bucketName, BlobId blobId) {
-        return Mono.from(backend.readBytes(bucketName, blobId));
+        return Mono.from(metricFactory.runPublishingTimerMetric(BLOBSTORE_BACKEND_LATENCY_METRIC_NAME,
+            () -> backend.readBytes(bucketName, blobId)));
     }
 }
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 ad6c3d3..a903d1c 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,7 @@ 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_BACKEND_LATENCY_METRIC_NAME;
 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.apache.james.blob.cassandra.cache.CachedBlobStore.BLOBSTORE_CACHED_MISS_COUNT_METRIC_NAME;
@@ -285,7 +286,7 @@ public class CachedBlobStoreTest implements BlobStoreContract {
     class MetricsTest {
         @Test
         public void readBlobStoreCacheWithNoneDefaultBucketNameShouldNotImpact() {
-            BlobId blobId = Mono.from(backend.save(TEST_BUCKETNAME, APPROXIMATELY_FIVE_KILOBYTES, SIZE_BASED)).block();
+            BlobId blobId = Mono.from(testee.save(TEST_BUCKETNAME, APPROXIMATELY_FIVE_KILOBYTES, SIZE_BASED)).block();
 
             testee.read(TEST_BUCKETNAME, blobId);
             testee.read(TEST_BUCKETNAME, blobId);
@@ -300,12 +301,15 @@ public class CachedBlobStoreTest implements BlobStoreContract {
                 assertThat(metricFactory.executionTimesFor(BLOBSTORE_CACHED_LATENCY_METRIC_NAME))
                     .describedAs(BLOBSTORE_CACHED_LATENCY_METRIC_NAME)
                     .hasSize(0);
+                assertThat(metricFactory.executionTimesFor(BLOBSTORE_BACKEND_LATENCY_METRIC_NAME))
+                    .describedAs(BLOBSTORE_BACKEND_LATENCY_METRIC_NAME)
+                    .hasSize(2);
             });
         }
 
         @Test
         public void readBytesWithNoneDefaultBucketNameShouldNotImpact() {
-            BlobId blobId = Mono.from(backend.save(TEST_BUCKETNAME, APPROXIMATELY_FIVE_KILOBYTES, SIZE_BASED)).block();
+            BlobId blobId = Mono.from(testee.save(TEST_BUCKETNAME, APPROXIMATELY_FIVE_KILOBYTES, SIZE_BASED)).block();
 
             Mono.from(testee.readBytes(TEST_BUCKETNAME, blobId)).block();
             Mono.from(testee.readBytes(TEST_BUCKETNAME, blobId)).block();
@@ -321,27 +325,47 @@ public class CachedBlobStoreTest implements BlobStoreContract {
                 assertThat(metricFactory.executionTimesFor(BLOBSTORE_CACHED_LATENCY_METRIC_NAME))
                     .describedAs(BLOBSTORE_CACHED_LATENCY_METRIC_NAME)
                     .hasSize(0);
+                assertThat(metricFactory.executionTimesFor(BLOBSTORE_BACKEND_LATENCY_METRIC_NAME))
+                    .describedAs(BLOBSTORE_BACKEND_LATENCY_METRIC_NAME)
+                    .hasSize(2);
             });
         }
 
         @Test
         public void readBlobStoreCacheShouldPublishTimerMetrics() {
-            BlobId blobId = Mono.from(backend.save(DEFAULT_BUCKETNAME, APPROXIMATELY_FIVE_KILOBYTES, SIZE_BASED)).block();
+            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.executionTimesFor(BLOBSTORE_CACHED_LATENCY_METRIC_NAME)).hasSize(2);
+            SoftAssertions.assertSoftly(soflty -> {
+                soflty.assertThat(metricFactory.executionTimesFor(BLOBSTORE_CACHED_LATENCY_METRIC_NAME))
+                    .describedAs(BLOBSTORE_CACHED_LATENCY_METRIC_NAME)
+                    .hasSize(2);
+                soflty.assertThat(metricFactory.executionTimesFor(BLOBSTORE_BACKEND_LATENCY_METRIC_NAME))
+                    .describedAs(BLOBSTORE_BACKEND_LATENCY_METRIC_NAME)
+                    .hasSize(0);
+            });
         }
 
         @Test
         public void readBytesCacheShouldPublishTimerMetrics() {
-            BlobId blobId = Mono.from(backend.save(DEFAULT_BUCKETNAME, APPROXIMATELY_FIVE_KILOBYTES, SIZE_BASED)).block();
+            BlobId blobId = Mono.from(testee.save(DEFAULT_BUCKETNAME, APPROXIMATELY_FIVE_KILOBYTES, SIZE_BASED)).block();
 
             Mono.from(testee.readBytes(DEFAULT_BUCKETNAME, blobId)).block();
             Mono.from(testee.readBytes(DEFAULT_BUCKETNAME, blobId)).block();
 
-            assertThat(metricFactory.executionTimesFor(BLOBSTORE_CACHED_LATENCY_METRIC_NAME)).hasSize(2);
+            SoftAssertions.assertSoftly(soflty -> {
+                soflty.assertThat(metricFactory.executionTimesFor(BLOBSTORE_CACHED_LATENCY_METRIC_NAME))
+                    .describedAs(BLOBSTORE_CACHED_LATENCY_METRIC_NAME)
+                    .hasSize(2);
+                soflty.assertThat(metricFactory.countFor(BLOBSTORE_CACHED_HIT_COUNT_METRIC_NAME))
+                    .describedAs(BLOBSTORE_CACHED_HIT_COUNT_METRIC_NAME)
+                    .isEqualTo(2);
+                soflty.assertThat(metricFactory.executionTimesFor(BLOBSTORE_BACKEND_LATENCY_METRIC_NAME))
+                    .describedAs(BLOBSTORE_BACKEND_LATENCY_METRIC_NAME)
+                    .hasSize(0);
+            });
         }
 
         @Test
@@ -352,7 +376,7 @@ public class CachedBlobStoreTest implements BlobStoreContract {
             Mono.from(testee.readBytes(DEFAULT_BUCKETNAME, blobId)).block();
 
             SoftAssertions.assertSoftly(soflty -> {
-                assertThat(metricFactory.countFor(BLOBSTORE_CACHED_MISS_COUNT_METRIC_NAME))
+                soflty.assertThat(metricFactory.countFor(BLOBSTORE_CACHED_MISS_COUNT_METRIC_NAME))
                     .describedAs(BLOBSTORE_CACHED_MISS_COUNT_METRIC_NAME)
                     .isEqualTo(0);
                 soflty.assertThat(metricFactory.countFor(BLOBSTORE_CACHED_HIT_COUNT_METRIC_NAME))
@@ -369,7 +393,7 @@ public class CachedBlobStoreTest implements BlobStoreContract {
             testee.read(DEFAULT_BUCKETNAME, blobId);
 
             SoftAssertions.assertSoftly(soflty -> {
-                assertThat(metricFactory.countFor(BLOBSTORE_CACHED_MISS_COUNT_METRIC_NAME))
+                soflty.assertThat(metricFactory.countFor(BLOBSTORE_CACHED_MISS_COUNT_METRIC_NAME))
                     .describedAs(BLOBSTORE_CACHED_MISS_COUNT_METRIC_NAME)
                     .isEqualTo(0);
                 soflty.assertThat(metricFactory.countFor(BLOBSTORE_CACHED_HIT_COUNT_METRIC_NAME))
@@ -403,8 +427,8 @@ public class CachedBlobStoreTest implements BlobStoreContract {
         @Test
         public void readBlobStoreCacheShouldCountWhenMissed() {
             BlobId blobId = Mono.from(backend.save(DEFAULT_BUCKETNAME, APPROXIMATELY_FIVE_KILOBYTES, SIZE_BASED)).block();
-            Mono.from(cache.remove(blobId)).block();
 
+            Mono.from(cache.remove(blobId)).block();
             testee.read(DEFAULT_BUCKETNAME, blobId);
 
             assertThat(metricFactory.countFor(BLOBSTORE_CACHED_MISS_COUNT_METRIC_NAME)).isEqualTo(1);
@@ -413,8 +437,8 @@ public class CachedBlobStoreTest implements BlobStoreContract {
         @Test
         public void readBytesCacheShouldCountWhenMissed() {
             BlobId blobId = Mono.from(backend.save(DEFAULT_BUCKETNAME, APPROXIMATELY_FIVE_KILOBYTES, SIZE_BASED)).block();
-            Mono.from(cache.remove(blobId)).block();
 
+            Mono.from(cache.remove(blobId)).block();
             Mono.from(testee.readBytes(DEFAULT_BUCKETNAME, blobId)).block();
 
             assertThat(metricFactory.countFor(BLOBSTORE_CACHED_MISS_COUNT_METRIC_NAME)).isEqualTo(1);
@@ -435,6 +459,9 @@ public class CachedBlobStoreTest implements BlobStoreContract {
                 soflty.assertThat(metricFactory.executionTimesFor(BLOBSTORE_CACHED_LATENCY_METRIC_NAME))
                     .describedAs(BLOBSTORE_CACHED_LATENCY_METRIC_NAME)
                     .hasSize(1);
+                soflty.assertThat(metricFactory.executionTimesFor(BLOBSTORE_BACKEND_LATENCY_METRIC_NAME))
+                    .describedAs(BLOBSTORE_BACKEND_LATENCY_METRIC_NAME)
+                    .hasSize(1);
             });
         }
 
@@ -453,6 +480,9 @@ public class CachedBlobStoreTest implements BlobStoreContract {
                 soflty.assertThat(metricFactory.executionTimesFor(BLOBSTORE_CACHED_LATENCY_METRIC_NAME))
                     .describedAs(BLOBSTORE_CACHED_LATENCY_METRIC_NAME)
                     .hasSize(1);
+                soflty.assertThat(metricFactory.executionTimesFor(BLOBSTORE_BACKEND_LATENCY_METRIC_NAME))
+                    .describedAs(BLOBSTORE_BACKEND_LATENCY_METRIC_NAME)
+                    .hasSize(1);
             });
         }
     }


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