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:51 UTC

[james-project] 03/06: JAMES-3170 Rename MetricFactory run methods

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 93e61a856deb7e9e3bef76eded8049699fe274f9
Author: duc91 <du...@gmail.com>
AuthorDate: Thu Jun 11 09:50:51 2020 +0700

    JAMES-3170 Rename MetricFactory run methods
    
    It allows disambiguating differences between suppliers and publishers
    as passing a Supplier<Publisher> has in non obvious results
---
 .../mailbox/events/delivery/InVmEventDelivery.java |  2 +-
 .../mailbox/events/MailboxListenerExecutor.java    |  2 +-
 .../vault/blob/BlobStoreDeletedMessageVault.java   | 10 +--
 .../james/mailbox/store/PreDeletionHooks.java      |  2 +-
 .../james/mailbox/tika/TikaTextExtractor.java      |  9 +-
 .../apache/james/metrics/api/MetricFactory.java    | 10 +--
 .../dropwizard/DropWizardMetricFactory.java        |  4 +-
 .../james/metrics/logger/DefaultMetricFactory.java |  4 +-
 .../metrics/tests/RecordingMetricFactory.java      |  4 +-
 .../metrics/tests/RecordingMetricFactoryTest.java  |  2 +-
 .../apache/james/blob/api/MetricableBlobStore.java | 12 +--
 .../blob/cassandra/cache/CachedBlobStore.java      | 35 +++++---
 .../blob/cassandra/cache/CachedBlobStoreTest.java  | 96 ++++++++++++++++------
 .../james/jmap/draft/methods/GetFilterMethod.java  |  2 +-
 .../jmap/draft/methods/GetMailboxesMethod.java     |  2 +-
 .../jmap/draft/methods/GetMessageListMethod.java   |  2 +-
 .../jmap/draft/methods/GetMessagesMethod.java      |  2 +-
 .../draft/methods/GetVacationResponseMethod.java   |  2 +-
 .../james/jmap/draft/methods/SendMDNProcessor.java |  2 +-
 .../james/jmap/draft/methods/SetFilterMethod.java  |  2 +-
 .../jmap/draft/methods/SetMailboxesMethod.java     |  2 +-
 .../methods/SetMessagesDestructionProcessor.java   |  2 +-
 .../jmap/draft/methods/SetMessagesMethod.java      |  2 +-
 .../draft/methods/SetVacationResponseMethod.java   |  2 +-
 .../james/jmap/http/AuthenticationRoutes.java      |  2 +-
 .../jmap/http/DefaultMailboxesProvisioner.java     |  2 +-
 .../org/apache/james/jmap/http/DownloadRoutes.java |  4 +-
 .../org/apache/james/jmap/http/JMAPApiRoutes.java  |  2 +-
 .../org/apache/james/jmap/http/UploadRoutes.java   |  2 +-
 .../james/jmap/method/MailboxGetMethod.scala       |  4 +-
 .../org/apache/james/jmap/http/Authenticator.java  |  2 +-
 .../james/spamassassin/SpamAssassinInvoker.java    |  8 +-
 32 files changed, 144 insertions(+), 96 deletions(-)

diff --git a/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/delivery/InVmEventDelivery.java b/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/delivery/InVmEventDelivery.java
index 369fe3f..f4f7036 100644
--- a/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/delivery/InVmEventDelivery.java
+++ b/mailbox/event/event-memory/src/main/java/org/apache/james/mailbox/events/delivery/InVmEventDelivery.java
@@ -79,7 +79,7 @@ public class InVmEventDelivery implements EventDelivery {
 
     private Mono<Void> doDeliverToListener(MailboxListener.ReactiveMailboxListener mailboxListener, Event event) {
         if (mailboxListener.isHandling(event)) {
-            return Mono.defer(() -> Mono.from(metricFactory.runPublishingTimerMetric(timerName(mailboxListener),
+            return Mono.defer(() -> Mono.from(metricFactory.decoratePublisherWithTimerMetric(timerName(mailboxListener),
                     mailboxListener.reactiveEvent(event))))
                 .subscriberContext(context("deliver", buildMDC(mailboxListener, event)));
         }
diff --git a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/MailboxListenerExecutor.java b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/MailboxListenerExecutor.java
index 32276ef..deb0098 100644
--- a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/MailboxListenerExecutor.java
+++ b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/MailboxListenerExecutor.java
@@ -36,7 +36,7 @@ class MailboxListenerExecutor {
 
     Mono<Void> execute(MailboxListener.ReactiveMailboxListener listener, MDCBuilder mdcBuilder, Event event) {
         if (listener.isHandling(event)) {
-            return Mono.from(metricFactory.runPublishingTimerMetric(timerName(listener),
+            return Mono.from(metricFactory.decoratePublisherWithTimerMetric(timerName(listener),
                 Mono.from(listener.reactiveEvent(event))
                     .subscriberContext(ReactorUtils.context("MailboxListenerExecutor", mdc(listener, mdcBuilder, event)))));
         }
diff --git a/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/blob/BlobStoreDeletedMessageVault.java b/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/blob/BlobStoreDeletedMessageVault.java
index a7bf391..8febe09 100644
--- a/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/blob/BlobStoreDeletedMessageVault.java
+++ b/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/blob/BlobStoreDeletedMessageVault.java
@@ -92,7 +92,7 @@ public class BlobStoreDeletedMessageVault implements DeletedMessageVault {
         Preconditions.checkNotNull(mimeMessage);
         BucketName bucketName = nameGenerator.currentBucket();
 
-        return metricFactory.runPublishingTimerMetric(
+        return metricFactory.decoratePublisherWithTimerMetric(
             APPEND_METRIC_NAME,
             appendMessage(deletedMessage, mimeMessage, bucketName));
     }
@@ -112,7 +112,7 @@ public class BlobStoreDeletedMessageVault implements DeletedMessageVault {
         Preconditions.checkNotNull(username);
         Preconditions.checkNotNull(messageId);
 
-        return metricFactory.runPublishingTimerMetric(
+        return metricFactory.decoratePublisherWithTimerMetric(
             LOAD_MIME_MESSAGE_METRIC_NAME,
             Mono.from(messageMetadataVault.retrieveStorageInformation(username, messageId))
                 .flatMap(storageInformation -> loadMimeMessage(storageInformation, username, messageId)));
@@ -130,7 +130,7 @@ public class BlobStoreDeletedMessageVault implements DeletedMessageVault {
         Preconditions.checkNotNull(username);
         Preconditions.checkNotNull(query);
 
-        return metricFactory.runPublishingTimerMetric(
+        return metricFactory.decoratePublisherWithTimerMetric(
             SEARCH_METRIC_NAME,
             searchOn(username, query));
     }
@@ -147,7 +147,7 @@ public class BlobStoreDeletedMessageVault implements DeletedMessageVault {
         Preconditions.checkNotNull(username);
         Preconditions.checkNotNull(messageId);
 
-        return metricFactory.runPublishingTimerMetric(
+        return metricFactory.decoratePublisherWithTimerMetric(
             DELETE_METRIC_NAME,
             deleteMessage(username, messageId));
     }
@@ -168,7 +168,7 @@ public class BlobStoreDeletedMessageVault implements DeletedMessageVault {
 
     Flux<BucketName> deleteExpiredMessages(ZonedDateTime beginningOfRetentionPeriod) {
         return Flux.from(
-            metricFactory.runPublishingTimerMetric(
+            metricFactory.decoratePublisherWithTimerMetric(
                 DELETE_EXPIRED_MESSAGES_METRIC_NAME,
                 retentionQualifiedBuckets(beginningOfRetentionPeriod)
                     .flatMap(bucketName -> deleteBucketData(bucketName).then(Mono.just(bucketName)))));
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/PreDeletionHooks.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/PreDeletionHooks.java
index b53e039..c56c87a 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/PreDeletionHooks.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/PreDeletionHooks.java
@@ -63,6 +63,6 @@ public class PreDeletionHooks {
 
     private Mono<Void> publishMetric(PreDeletionHook.DeleteOperation deleteOperation, PreDeletionHook hook, MetricFactory factory) {
         return Mono.from(
-            factory.runPublishingTimerMetric(PRE_DELETION_HOOK_METRIC_NAME, hook.notifyDelete(deleteOperation)));
+            factory.decoratePublisherWithTimerMetric(PRE_DELETION_HOOK_METRIC_NAME, hook.notifyDelete(deleteOperation)));
     }
 }
diff --git a/mailbox/tika/src/main/java/org/apache/james/mailbox/tika/TikaTextExtractor.java b/mailbox/tika/src/main/java/org/apache/james/mailbox/tika/TikaTextExtractor.java
index b20da09..78b0eed 100644
--- a/mailbox/tika/src/main/java/org/apache/james/mailbox/tika/TikaTextExtractor.java
+++ b/mailbox/tika/src/main/java/org/apache/james/mailbox/tika/TikaTextExtractor.java
@@ -37,13 +37,10 @@ import org.apache.james.mailbox.model.ContentType;
 import org.apache.james.mailbox.store.extractor.JsoupTextExtractor;
 import org.apache.james.metrics.api.MetricFactory;
 
-import com.fasterxml.jackson.core.JsonParseException;
 import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.core.TreeNode;
 import com.fasterxml.jackson.databind.DeserializationContext;
 import com.fasterxml.jackson.databind.JsonDeserializer;
-import com.fasterxml.jackson.databind.JsonMappingException;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.module.SimpleModule;
@@ -85,7 +82,7 @@ public class TikaTextExtractor implements TextExtractor {
         if (contentType.mediaType().equals(TEXT)) {
             return jsoupTextExtractor.extractContent(inputStream, contentType);
         }
-        return metricFactory.runPublishingTimerMetric("tikaTextExtraction", Throwing.supplier(
+        return metricFactory.decorateSupplierWithTimerMetric("tikaTextExtraction", Throwing.supplier(
             () -> performContentExtraction(inputStream, contentType))
             .sneakyThrow());
     }
@@ -95,7 +92,7 @@ public class TikaTextExtractor implements TextExtractor {
         return new ParsedContent(contentAndMetadata.getContent(), contentAndMetadata.getMetadata());
     }
 
-    private ContentAndMetadata convert(Optional<InputStream> maybeInputStream) throws IOException, JsonParseException, JsonMappingException {
+    private ContentAndMetadata convert(Optional<InputStream> maybeInputStream) throws IOException {
         return maybeInputStream
                 .map(Throwing.function(inputStream -> objectMapper.readValue(inputStream, ContentAndMetadata.class)))
                 .orElse(ContentAndMetadata.empty());
@@ -105,7 +102,7 @@ public class TikaTextExtractor implements TextExtractor {
     static class ContentAndMetadataDeserializer extends JsonDeserializer<ContentAndMetadata> {
 
         @Override
-        public ContentAndMetadata deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+        public ContentAndMetadata deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
             TreeNode treeNode = jsonParser.getCodec().readTree(jsonParser);
             Preconditions.checkState(treeNode.isArray() && treeNode.size() >= 1, "The response should be an array with at least one element");
             Preconditions.checkState(treeNode.get(0).isObject(), "The element should be a Json object");
diff --git a/metrics/metrics-api/src/main/java/org/apache/james/metrics/api/MetricFactory.java b/metrics/metrics-api/src/main/java/org/apache/james/metrics/api/MetricFactory.java
index 2c0b464..adb64a1 100644
--- a/metrics/metrics-api/src/main/java/org/apache/james/metrics/api/MetricFactory.java
+++ b/metrics/metrics-api/src/main/java/org/apache/james/metrics/api/MetricFactory.java
@@ -31,7 +31,7 @@ public interface MetricFactory {
 
     TimeMetric timer(String name);
 
-    default <T> T runPublishingTimerMetric(String name, Supplier<T> operation) {
+    default <T> T decorateSupplierWithTimerMetric(String name, Supplier<T> operation) {
         TimeMetric timer = timer(name);
         try {
             return operation.get();
@@ -40,7 +40,7 @@ public interface MetricFactory {
         }
     }
 
-    default <T> T runPublishingTimerMetricLogP99(String name, Supplier<T> operation) {
+    default <T> T decorateSupplierWithTimerMetricLogP99(String name, Supplier<T> operation) {
         TimeMetric timer = timer(name);
         try {
             return operation.get();
@@ -49,12 +49,12 @@ public interface MetricFactory {
         }
     }
 
-    <T> Publisher<T> runPublishingTimerMetric(String name, Publisher<T> publisher);
+    <T> Publisher<T> decoratePublisherWithTimerMetric(String name, Publisher<T> publisher);
 
-    <T> Publisher<T> runPublishingTimerMetricLogP99(String name, Publisher<T> publisher);
+    <T> Publisher<T> decoratePublisherWithTimerMetricLogP99(String name, Publisher<T> publisher);
 
     default void runPublishingTimerMetric(String name, Runnable runnable) {
-        runPublishingTimerMetric(name, () -> {
+        decorateSupplierWithTimerMetric(name, () -> {
             runnable.run();
             return null;
         });
diff --git a/metrics/metrics-dropwizard/src/main/java/org/apache/james/metrics/dropwizard/DropWizardMetricFactory.java b/metrics/metrics-dropwizard/src/main/java/org/apache/james/metrics/dropwizard/DropWizardMetricFactory.java
index e65fbb7..2b0081c 100644
--- a/metrics/metrics-dropwizard/src/main/java/org/apache/james/metrics/dropwizard/DropWizardMetricFactory.java
+++ b/metrics/metrics-dropwizard/src/main/java/org/apache/james/metrics/dropwizard/DropWizardMetricFactory.java
@@ -59,13 +59,13 @@ public class DropWizardMetricFactory implements MetricFactory, Startable {
     }
 
     @Override
-    public <T> Publisher<T> runPublishingTimerMetric(String name, Publisher<T> publisher) {
+    public <T> Publisher<T> decoratePublisherWithTimerMetric(String name, Publisher<T> publisher) {
         TimeMetric timer = timer(name);
         return Flux.from(publisher).doOnComplete(timer::stopAndPublish);
     }
 
     @Override
-    public <T> Publisher<T> runPublishingTimerMetricLogP99(String name, Publisher<T> publisher) {
+    public <T> Publisher<T> decoratePublisherWithTimerMetricLogP99(String name, Publisher<T> publisher) {
         TimeMetric timer = timer(name);
         return Flux.from(publisher)
             .doOnComplete(() -> timer.stopAndPublish().logWhenExceedP99(DEFAULT_100_MS_THRESHOLD));
diff --git a/metrics/metrics-logger/src/main/java/org/apache/james/metrics/logger/DefaultMetricFactory.java b/metrics/metrics-logger/src/main/java/org/apache/james/metrics/logger/DefaultMetricFactory.java
index 373d813..919363c 100644
--- a/metrics/metrics-logger/src/main/java/org/apache/james/metrics/logger/DefaultMetricFactory.java
+++ b/metrics/metrics-logger/src/main/java/org/apache/james/metrics/logger/DefaultMetricFactory.java
@@ -44,13 +44,13 @@ public class DefaultMetricFactory implements MetricFactory {
     }
 
     @Override
-    public <T> Publisher<T> runPublishingTimerMetric(String name, Publisher<T> publisher) {
+    public <T> Publisher<T> decoratePublisherWithTimerMetric(String name, Publisher<T> publisher) {
         TimeMetric timer = timer(name);
         return Flux.from(publisher).doOnComplete(timer::stopAndPublish);
     }
 
     @Override
-    public <T> Publisher<T> runPublishingTimerMetricLogP99(String name, Publisher<T> publisher) {
+    public <T> Publisher<T> decoratePublisherWithTimerMetricLogP99(String name, Publisher<T> publisher) {
         TimeMetric timer = timer(name);
         return Flux.from(publisher)
             .doOnComplete(() -> timer.stopAndPublish().logWhenExceedP99(DEFAULT_100_MS_THRESHOLD));
diff --git a/metrics/metrics-tests/src/main/java/org/apache/james/metrics/tests/RecordingMetricFactory.java b/metrics/metrics-tests/src/main/java/org/apache/james/metrics/tests/RecordingMetricFactory.java
index 99d293f..63a8922 100644
--- a/metrics/metrics-tests/src/main/java/org/apache/james/metrics/tests/RecordingMetricFactory.java
+++ b/metrics/metrics-tests/src/main/java/org/apache/james/metrics/tests/RecordingMetricFactory.java
@@ -62,13 +62,13 @@ public class RecordingMetricFactory implements MetricFactory {
     }
 
     @Override
-    public <T> Publisher<T> runPublishingTimerMetric(String name, Publisher<T> publisher) {
+    public <T> Publisher<T> decoratePublisherWithTimerMetric(String name, Publisher<T> publisher) {
         TimeMetric timer = timer(name);
         return Flux.from(publisher).doOnComplete(timer::stopAndPublish);
     }
 
     @Override
-    public <T> Publisher<T> runPublishingTimerMetricLogP99(String name, Publisher<T> publisher) {
+    public <T> Publisher<T> decoratePublisherWithTimerMetricLogP99(String name, Publisher<T> publisher) {
         TimeMetric timer = timer(name);
         return Flux.from(publisher)
             .doOnComplete(() -> timer.stopAndPublish().logWhenExceedP99(DEFAULT_100_MS_THRESHOLD));
diff --git a/metrics/metrics-tests/src/test/java/org/apache/james/metrics/tests/RecordingMetricFactoryTest.java b/metrics/metrics-tests/src/test/java/org/apache/james/metrics/tests/RecordingMetricFactoryTest.java
index eb39585..c125ea3 100644
--- a/metrics/metrics-tests/src/test/java/org/apache/james/metrics/tests/RecordingMetricFactoryTest.java
+++ b/metrics/metrics-tests/src/test/java/org/apache/james/metrics/tests/RecordingMetricFactoryTest.java
@@ -78,7 +78,7 @@ class RecordingMetricFactoryTest implements MetricFactoryContract {
         AtomicInteger count = new AtomicInteger();
 
         ConcurrentTestRunner.builder()
-            .operation((threadNumber, step) -> testee.runPublishingTimerMetric(TIME_METRIC_NAME, count::incrementAndGet))
+            .operation((threadNumber, step) -> testee.decorateSupplierWithTimerMetric(TIME_METRIC_NAME, count::incrementAndGet))
             .threadCount(10)
             .operationCount(200)
             .runSuccessfullyWithin(Duration.ofSeconds(10));
diff --git a/server/blob/blob-api/src/main/java/org/apache/james/blob/api/MetricableBlobStore.java b/server/blob/blob-api/src/main/java/org/apache/james/blob/api/MetricableBlobStore.java
index 0e4e383..309a20e 100644
--- a/server/blob/blob-api/src/main/java/org/apache/james/blob/api/MetricableBlobStore.java
+++ b/server/blob/blob-api/src/main/java/org/apache/james/blob/api/MetricableBlobStore.java
@@ -50,28 +50,28 @@ public class MetricableBlobStore implements BlobStore {
 
     @Override
     public Publisher<BlobId> save(BucketName bucketName, byte[] data, StoragePolicy storagePolicy) {
-        return metricFactory.runPublishingTimerMetric(SAVE_BYTES_TIMER_NAME, blobStoreImpl.save(bucketName, data, storagePolicy));
+        return metricFactory.decoratePublisherWithTimerMetric(SAVE_BYTES_TIMER_NAME, blobStoreImpl.save(bucketName, data, storagePolicy));
     }
 
     @Override
     public Publisher<BlobId> save(BucketName bucketName, InputStream data, StoragePolicy storagePolicy) {
-        return metricFactory.runPublishingTimerMetric(SAVE_INPUT_STREAM_TIMER_NAME, blobStoreImpl.save(bucketName, data, storagePolicy));
+        return metricFactory.decoratePublisherWithTimerMetric(SAVE_INPUT_STREAM_TIMER_NAME, blobStoreImpl.save(bucketName, data, storagePolicy));
     }
 
     @Override
     public Publisher<byte[]> readBytes(BucketName bucketName, BlobId blobId) {
-        return metricFactory.runPublishingTimerMetric(READ_BYTES_TIMER_NAME, blobStoreImpl.readBytes(bucketName, blobId));
+        return metricFactory.decoratePublisherWithTimerMetric(READ_BYTES_TIMER_NAME, blobStoreImpl.readBytes(bucketName, blobId));
     }
 
     @Override
     public InputStream read(BucketName bucketName, BlobId blobId) {
         return metricFactory
-            .runPublishingTimerMetric(READ_TIMER_NAME, () -> blobStoreImpl.read(bucketName, blobId));
+            .decorateSupplierWithTimerMetric(READ_TIMER_NAME, () -> blobStoreImpl.read(bucketName, blobId));
     }
 
     @Override
     public Publisher<Void> deleteBucket(BucketName bucketName) {
-        return metricFactory.runPublishingTimerMetric(DELETE_BUCKET_TIMER_NAME, blobStoreImpl.deleteBucket(bucketName));
+        return metricFactory.decoratePublisherWithTimerMetric(DELETE_BUCKET_TIMER_NAME, blobStoreImpl.deleteBucket(bucketName));
     }
 
     @Override
@@ -81,7 +81,7 @@ public class MetricableBlobStore implements BlobStore {
 
     @Override
     public Publisher<Void> delete(BucketName bucketName, BlobId blobId) {
-        return metricFactory.runPublishingTimerMetric(DELETE_TIMER_NAME, blobStoreImpl.delete(bucketName, blobId));
+        return metricFactory.decoratePublisherWithTimerMetric(DELETE_TIMER_NAME, blobStoreImpl.delete(bucketName, blobId));
     }
 
 }
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 1a14773..48a8cfd 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
@@ -38,6 +38,7 @@ 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.apache.james.metrics.api.TimeMetric;
 import org.reactivestreams.Publisher;
 
 import com.google.common.base.Preconditions;
@@ -153,18 +154,23 @@ public class CachedBlobStore implements BlobStore {
 
     @Override
     public Mono<byte[]> readBytes(BucketName bucketName, BlobId blobId) {
-        return Mono.just(bucketName)
-            .filter(getDefaultBucketName()::equals)
-            .flatMap(deleteBucket -> readBytesInDefaultBucket(bucketName, blobId))
-            .switchIfEmpty(Mono.defer(() -> readBytesFromBackend(bucketName, blobId)));
+        if (getDefaultBucketName().equals(bucketName)) {
+            return readBytesInDefaultBucket(bucketName, blobId);
+        }
+        return readBytesFromBackend(bucketName, blobId);
     }
 
     private Mono<byte[]> readBytesInDefaultBucket(BucketName bucketName, BlobId blobId) {
-        return readFromCache(blobId)
-            .switchIfEmpty(Mono.defer(() -> readBytesFromBackend(bucketName, blobId))
-                .filter(this::isAbleToCache)
-                .doOnNext(any -> metricRetrieveMissCount.increment())
-                .flatMap(bytes -> saveInCache(blobId, bytes).then(Mono.just(bytes))));
+        return readFromCache(blobId).switchIfEmpty(
+            readBytesFromBackend(bucketName, blobId)
+                .flatMap(bytes -> {
+                    if (isAbleToCache(bytes)) {
+                        metricRetrieveMissCount.increment();
+                        return saveInCache(blobId, bytes)
+                            .then(Mono.just(bytes));
+                    }
+                    return Mono.just(bytes);
+                }));
     }
 
     @Override
@@ -261,17 +267,20 @@ public class CachedBlobStore implements BlobStore {
     }
 
     private Mono<byte[]> readFromCache(BlobId blobId) {
-        return Mono.from(metricFactory.runPublishingTimerMetric(BLOBSTORE_CACHED_LATENCY_METRIC_NAME, cache.read(blobId)))
+        return Mono.from(metricFactory.decoratePublisherWithTimerMetric(BLOBSTORE_CACHED_LATENCY_METRIC_NAME, cache.read(blobId)))
             .doOnNext(any -> metricRetrieveHitCount.increment());
     }
 
     private Mono<InputStream> readFromBackend(BucketName bucketName, BlobId blobId) {
-        return Mono.from(metricFactory.runPublishingTimerMetric(BLOBSTORE_BACKEND_LATENCY_METRIC_NAME,
+        return Mono.from(metricFactory.decoratePublisherWithTimerMetric(BLOBSTORE_BACKEND_LATENCY_METRIC_NAME,
             Mono.fromCallable(() -> backend.read(bucketName, blobId))));
     }
 
     private Mono<byte[]> readBytesFromBackend(BucketName bucketName, BlobId blobId) {
-        return Mono.from(metricFactory.runPublishingTimerMetric(BLOBSTORE_BACKEND_LATENCY_METRIC_NAME,
-            () -> backend.readBytes(bucketName, blobId)));
+        TimeMetric timer = metricFactory.timer(BLOBSTORE_BACKEND_LATENCY_METRIC_NAME);
+
+        return Mono.from(backend.readBytes(bucketName, blobId))
+            .doOnSuccess(any -> timer.stopAndPublish())
+            .doOnError(ObjectNotFoundException.class, any -> timer.stopAndPublish());
     }
 }
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 a903d1c..5caff3f 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
@@ -272,7 +272,7 @@ public class CachedBlobStoreTest implements BlobStoreContract {
 
     @Test
     public void shouldNotCacheWhenReadWithBigStream() {
-        BlobId blobId = Mono.from(backend.save(DEFAULT_BUCKETNAME, new ByteArrayInputStream(TWELVE_MEGABYTES), SIZE_BASED)).block();
+        BlobId blobId = Mono.from(testee.save(DEFAULT_BUCKETNAME, new ByteArrayInputStream(TWELVE_MEGABYTES), SIZE_BASED)).block();
 
         SoftAssertions.assertSoftly(soflty -> {
             soflty.assertThat(Mono.from(cache.read(blobId)).blockOptional()).isEmpty();
@@ -285,30 +285,40 @@ public class CachedBlobStoreTest implements BlobStoreContract {
     @Nested
     class MetricsTest {
         @Test
-        public void readBlobStoreCacheWithNoneDefaultBucketNameShouldNotImpact() {
+        void readBlobStoreCacheWithNoneDefaultBucketNameShouldNotImpact() {
             BlobId blobId = Mono.from(testee.save(TEST_BUCKETNAME, APPROXIMATELY_FIVE_KILOBYTES, SIZE_BASED)).block();
 
             testee.read(TEST_BUCKETNAME, blobId);
             testee.read(TEST_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))
                     .describedAs(BLOBSTORE_CACHED_HIT_COUNT_METRIC_NAME)
                     .isEqualTo(0);
-                assertThat(metricFactory.executionTimesFor(BLOBSTORE_CACHED_LATENCY_METRIC_NAME))
+                soflty.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() {
+        void readBlobStoreWithNoneDefaultBucketNameShouldRecordByBackendLatency() {
+            BlobId blobId = Mono.from(testee.save(TEST_BUCKETNAME, APPROXIMATELY_FIVE_KILOBYTES, SIZE_BASED)).block();
+
+            testee.read(TEST_BUCKETNAME, blobId);
+            testee.read(TEST_BUCKETNAME, blobId);
+
+            SoftAssertions.assertSoftly(soflty ->
+                soflty.assertThat(metricFactory.executionTimesFor(BLOBSTORE_BACKEND_LATENCY_METRIC_NAME))
+                    .describedAs(BLOBSTORE_BACKEND_LATENCY_METRIC_NAME)
+                    .hasSize(2));
+        }
+
+        @Test
+        void readBytesWithNoneDefaultBucketNameShouldNotImpact() {
             BlobId blobId = Mono.from(testee.save(TEST_BUCKETNAME, APPROXIMATELY_FIVE_KILOBYTES, SIZE_BASED)).block();
 
             Mono.from(testee.readBytes(TEST_BUCKETNAME, blobId)).block();
@@ -322,17 +332,30 @@ public class CachedBlobStoreTest implements BlobStoreContract {
                 soflty.assertThat(metricFactory.countFor(BLOBSTORE_CACHED_HIT_COUNT_METRIC_NAME))
                     .describedAs(BLOBSTORE_CACHED_HIT_COUNT_METRIC_NAME)
                     .isEqualTo(0);
-                assertThat(metricFactory.executionTimesFor(BLOBSTORE_CACHED_LATENCY_METRIC_NAME))
+                soflty.assertThat(metricFactory.executionTimesFor(BLOBSTORE_CACHED_LATENCY_METRIC_NAME))
                     .describedAs(BLOBSTORE_CACHED_LATENCY_METRIC_NAME)
                     .hasSize(0);
-                assertThat(metricFactory.executionTimesFor(BLOBSTORE_BACKEND_LATENCY_METRIC_NAME))
+                soflty.assertThat(metricFactory.executionTimesFor(BLOBSTORE_BACKEND_LATENCY_METRIC_NAME))
                     .describedAs(BLOBSTORE_BACKEND_LATENCY_METRIC_NAME)
                     .hasSize(2);
             });
         }
 
         @Test
-        public void readBlobStoreCacheShouldPublishTimerMetrics() {
+        void readBytesWithNoneDefaultBucketNameShouldPublishBackendTimerMetrics() {
+            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();
+
+            SoftAssertions.assertSoftly(soflty ->
+                soflty.assertThat(metricFactory.executionTimesFor(BLOBSTORE_BACKEND_LATENCY_METRIC_NAME))
+                    .describedAs(BLOBSTORE_BACKEND_LATENCY_METRIC_NAME)
+                    .hasSize(2));
+        }
+
+        @Test
+        void readBlobStoreCacheShouldPublishTimerMetrics() {
             BlobId blobId = Mono.from(testee.save(DEFAULT_BUCKETNAME, APPROXIMATELY_FIVE_KILOBYTES, SIZE_BASED)).block();
 
             testee.read(DEFAULT_BUCKETNAME, blobId);
@@ -342,14 +365,11 @@ public class CachedBlobStoreTest implements BlobStoreContract {
                 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() {
+        void readBytesCacheShouldPublishTimerMetrics() {
             BlobId blobId = Mono.from(testee.save(DEFAULT_BUCKETNAME, APPROXIMATELY_FIVE_KILOBYTES, SIZE_BASED)).block();
 
             Mono.from(testee.readBytes(DEFAULT_BUCKETNAME, blobId)).block();
@@ -362,14 +382,37 @@ public class CachedBlobStoreTest implements BlobStoreContract {
                 soflty.assertThat(metricFactory.countFor(BLOBSTORE_CACHED_HIT_COUNT_METRIC_NAME))
                     .describedAs(BLOBSTORE_CACHED_HIT_COUNT_METRIC_NAME)
                     .isEqualTo(2);
+            });
+        }
+
+        @Test
+        void readBytesShouldPublishBackendTimerMetricsForBigBlobs() {
+            BlobId blobId = Mono.from(backend.save(DEFAULT_BUCKETNAME, ELEVEN_KILOBYTES, SIZE_BASED)).block();
+
+            Mono.from(testee.readBytes(DEFAULT_BUCKETNAME, blobId)).block();
+            Mono.from(testee.readBytes(DEFAULT_BUCKETNAME, blobId)).block();
+
+            SoftAssertions.assertSoftly(soflty ->
                 soflty.assertThat(metricFactory.executionTimesFor(BLOBSTORE_BACKEND_LATENCY_METRIC_NAME))
                     .describedAs(BLOBSTORE_BACKEND_LATENCY_METRIC_NAME)
-                    .hasSize(0);
-            });
+                    .hasSize(2));
         }
 
         @Test
-        public void readBytesShouldNotIncreaseCacheCounterForBigBlobs() {
+        void readInputStreamShouldPublishBackendTimerForBigBlobs() {
+            BlobId blobId = Mono.from(backend.save(DEFAULT_BUCKETNAME, ELEVEN_KILOBYTES, SIZE_BASED)).block();
+
+            testee.read(DEFAULT_BUCKETNAME, blobId);
+            testee.read(DEFAULT_BUCKETNAME, blobId);
+
+            SoftAssertions.assertSoftly(soflty ->
+                soflty.assertThat(metricFactory.executionTimesFor(BLOBSTORE_BACKEND_LATENCY_METRIC_NAME))
+                    .describedAs(BLOBSTORE_BACKEND_LATENCY_METRIC_NAME)
+                    .hasSize(2));
+        }
+
+        @Test
+        void readBytesShouldNotIncreaseCacheCounterForBigBlobs() {
             BlobId blobId = Mono.from(backend.save(DEFAULT_BUCKETNAME, ELEVEN_KILOBYTES, SIZE_BASED)).block();
 
             Mono.from(testee.readBytes(DEFAULT_BUCKETNAME, blobId)).block();
@@ -386,7 +429,7 @@ public class CachedBlobStoreTest implements BlobStoreContract {
         }
 
         @Test
-        public void readInputStreamShouldNotIncreaseCacheCounterForBigBlobs() {
+        void readInputStreamShouldNotIncreaseCacheCounterForBigBlobs() {
             BlobId blobId = Mono.from(backend.save(DEFAULT_BUCKETNAME, ELEVEN_KILOBYTES, SIZE_BASED)).block();
 
             testee.read(DEFAULT_BUCKETNAME, blobId);
@@ -402,9 +445,8 @@ public class CachedBlobStoreTest implements BlobStoreContract {
             });
         }
 
-
         @Test
-        public void readBlobStoreCacheShouldCountWhenHit() {
+        void readBlobStoreCacheShouldCountWhenHit() {
             BlobId blobId = Mono.from(testee.save(DEFAULT_BUCKETNAME, APPROXIMATELY_FIVE_KILOBYTES, SIZE_BASED)).block();
 
             testee.read(DEFAULT_BUCKETNAME, blobId);
@@ -414,7 +456,7 @@ public class CachedBlobStoreTest implements BlobStoreContract {
         }
 
         @Test
-        public void readBytesCacheShouldCountWhenHit() {
+        void readBytesCacheShouldCountWhenHit() {
             BlobId blobId = Mono.from(testee.save(DEFAULT_BUCKETNAME, APPROXIMATELY_FIVE_KILOBYTES, SIZE_BASED)).block();
 
             Mono.from(testee.readBytes(DEFAULT_BUCKETNAME, blobId)).block();
@@ -425,7 +467,7 @@ public class CachedBlobStoreTest implements BlobStoreContract {
 
 
         @Test
-        public void readBlobStoreCacheShouldCountWhenMissed() {
+        void readBlobStoreCacheShouldCountWhenMissed() {
             BlobId blobId = Mono.from(backend.save(DEFAULT_BUCKETNAME, APPROXIMATELY_FIVE_KILOBYTES, SIZE_BASED)).block();
 
             Mono.from(cache.remove(blobId)).block();
@@ -435,8 +477,8 @@ public class CachedBlobStoreTest implements BlobStoreContract {
         }
 
         @Test
-        public void readBytesCacheShouldCountWhenMissed() {
-            BlobId blobId = Mono.from(backend.save(DEFAULT_BUCKETNAME, APPROXIMATELY_FIVE_KILOBYTES, SIZE_BASED)).block();
+        void readBytesCacheShouldCountWhenMissed() {
+            BlobId blobId = Mono.from(testee.save(DEFAULT_BUCKETNAME, APPROXIMATELY_FIVE_KILOBYTES, SIZE_BASED)).block();
 
             Mono.from(cache.remove(blobId)).block();
             Mono.from(testee.readBytes(DEFAULT_BUCKETNAME, blobId)).block();
@@ -445,7 +487,7 @@ public class CachedBlobStoreTest implements BlobStoreContract {
         }
 
         @Test
-        public void metricsShouldNotWorkExceptLatencyWhenReadNonExistingBlob() {
+        void metricsShouldNotWorkExceptLatencyWhenReadNonExistingBlob() {
             SoftAssertions.assertSoftly(soflty -> {
                 soflty.assertThatThrownBy(() -> testee.read(DEFAULT_BUCKETNAME, new TestBlobId.Factory().randomId()))
                     .isInstanceOf(ObjectNotFoundException.class);
@@ -466,7 +508,7 @@ public class CachedBlobStoreTest implements BlobStoreContract {
         }
 
         @Test
-        public void metricsShouldNotWorkExceptLatencyWhenReadNonExistingBlobAsBytes() {
+        void metricsShouldNotWorkExceptLatencyWhenReadNonExistingBlobAsBytes() {
             SoftAssertions.assertSoftly(soflty -> {
                 soflty.assertThatThrownBy(() -> Mono.from(testee.readBytes(DEFAULT_BUCKETNAME, new TestBlobId.Factory().randomId())).blockOptional())
                     .isInstanceOf(ObjectNotFoundException.class);
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetFilterMethod.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetFilterMethod.java
index 6c1ca63..ebf9b53 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetFilterMethod.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetFilterMethod.java
@@ -75,7 +75,7 @@ public class GetFilterMethod implements Method {
 
         GetFilterRequest filterRequest = (GetFilterRequest) request;
 
-        return Flux.from(metricFactory.runPublishingTimerMetricLogP99(JMAP_PREFIX + METHOD_NAME.getName(),
+        return Flux.from(metricFactory.decorateSupplierWithTimerMetricLogP99(JMAP_PREFIX + METHOD_NAME.getName(),
             () -> process(methodCallId, mailboxSession, filterRequest)
                 .subscriberContext(context("GET_FILTER", MDCBuilder.of(MDCBuilder.ACTION, "GET_FILTER")))));
     }
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetMailboxesMethod.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetMailboxesMethod.java
index f5936a9..43396a7 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetMailboxesMethod.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetMailboxesMethod.java
@@ -95,7 +95,7 @@ public class GetMailboxesMethod implements Method {
         Preconditions.checkArgument(request instanceof GetMailboxesRequest);
         GetMailboxesRequest mailboxesRequest = (GetMailboxesRequest) request;
 
-        return metricFactory.runPublishingTimerMetricLogP99(JMAP_PREFIX + METHOD_NAME.getName(),
+        return metricFactory.decorateSupplierWithTimerMetricLogP99(JMAP_PREFIX + METHOD_NAME.getName(),
             () -> process(methodCallId, mailboxSession, mailboxesRequest)
             .subscriberContext(context(ACTION, mdc(mailboxesRequest))));
     }
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetMessageListMethod.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetMessageListMethod.java
index 39dc573..a14069c 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetMessageListMethod.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetMessageListMethod.java
@@ -101,7 +101,7 @@ public class GetMessageListMethod implements Method {
 
         GetMessageListRequest messageListRequest = (GetMessageListRequest) request;
 
-        return metricFactory.runPublishingTimerMetricLogP99(JMAP_PREFIX + METHOD_NAME.getName(),
+        return metricFactory.decorateSupplierWithTimerMetricLogP99(JMAP_PREFIX + METHOD_NAME.getName(),
             () -> process(methodCallId, mailboxSession, messageListRequest)
                 .subscriberContext(context("GET_MESSAGE_LIST", mdc(messageListRequest))))
             .subscribeOn(Schedulers.elastic());
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetMessagesMethod.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetMessagesMethod.java
index 59f2731..1532525 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetMessagesMethod.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetMessagesMethod.java
@@ -83,7 +83,7 @@ public class GetMessagesMethod implements Method {
         GetMessagesRequest getMessagesRequest = (GetMessagesRequest) request;
         MessageProperties outputProperties = getMessagesRequest.getProperties().toOutputProperties();
 
-        return metricFactory.runPublishingTimerMetricLogP99(JMAP_PREFIX + METHOD_NAME.getName(),
+        return metricFactory.decorateSupplierWithTimerMetricLogP99(JMAP_PREFIX + METHOD_NAME.getName(),
             () -> Flux.from(getMessagesResponse(mailboxSession, getMessagesRequest)
                 .map(response -> JmapResponse.builder().methodCallId(methodCallId)
                     .response(response)
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetVacationResponseMethod.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetVacationResponseMethod.java
index da9f326..e47af51 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetVacationResponseMethod.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetVacationResponseMethod.java
@@ -72,7 +72,7 @@ public class GetVacationResponseMethod implements Method {
         Preconditions.checkNotNull(mailboxSession);
         Preconditions.checkArgument(request instanceof GetVacationRequest);
 
-        return Flux.from(metricFactory.runPublishingTimerMetricLogP99(JMAP_PREFIX + METHOD_NAME.getName(),
+        return Flux.from(metricFactory.decoratePublisherWithTimerMetricLogP99(JMAP_PREFIX + METHOD_NAME.getName(),
             process(mailboxSession)
                 .map(response -> JmapResponse.builder()
                     .methodCallId(methodCallId)
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SendMDNProcessor.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SendMDNProcessor.java
index 98f6675..0fb3bea 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SendMDNProcessor.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SendMDNProcessor.java
@@ -77,7 +77,7 @@ public class SendMDNProcessor implements SetMessagesProcessor {
 
     @Override
     public SetMessagesResponse process(SetMessagesRequest request, MailboxSession mailboxSession) {
-        return metricFactory.runPublishingTimerMetricLogP99(JMAP_PREFIX + "SendMDN",
+        return metricFactory.decorateSupplierWithTimerMetricLogP99(JMAP_PREFIX + "SendMDN",
             () -> handleMDNCreation(request, mailboxSession));
     }
 
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetFilterMethod.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetFilterMethod.java
index f0ac91a..154aefa 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetFilterMethod.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetFilterMethod.java
@@ -118,7 +118,7 @@ public class SetFilterMethod implements Method {
 
         SetFilterRequest setFilterRequest = (SetFilterRequest) request;
 
-        return Flux.from(metricFactory.runPublishingTimerMetricLogP99(JMAP_PREFIX + METHOD_NAME.getName(),
+        return Flux.from(metricFactory.decorateSupplierWithTimerMetricLogP99(JMAP_PREFIX + METHOD_NAME.getName(),
             () -> process(methodCallId, mailboxSession, setFilterRequest)
                 .subscriberContext(jmapAction("SET_FILTER"))
                 .subscriberContext(context("SET_FILTER", MDCBuilder.of("update", setFilterRequest.getSingleton())))));
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetMailboxesMethod.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetMailboxesMethod.java
index 32291fe..9a0ffbf 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetMailboxesMethod.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetMailboxesMethod.java
@@ -74,7 +74,7 @@ public class SetMailboxesMethod implements Method {
             .addContext("update", setMailboxesRequest.getUpdate())
             .addContext("destroy", setMailboxesRequest.getDestroy())
             .wrapArround(
-                () -> metricFactory.runPublishingTimerMetricLogP99(JMAP_PREFIX + METHOD_NAME.getName(),
+                () -> metricFactory.decorateSupplierWithTimerMetricLogP99(JMAP_PREFIX + METHOD_NAME.getName(),
                     () -> Stream.of(
                         JmapResponse.builder().methodCallId(methodCallId)
                             .response(setMailboxesResponse(setMailboxesRequest, mailboxSession))
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetMessagesDestructionProcessor.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetMessagesDestructionProcessor.java
index c6ee87c..a961a73 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetMessagesDestructionProcessor.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetMessagesDestructionProcessor.java
@@ -56,7 +56,7 @@ public class SetMessagesDestructionProcessor implements SetMessagesProcessor {
 
     @Override
     public SetMessagesResponse process(SetMessagesRequest request, MailboxSession mailboxSession) {
-        return metricFactory.runPublishingTimerMetric(JMAP_PREFIX + "SetMessageDestructionProcessor",
+        return metricFactory.decorateSupplierWithTimerMetric(JMAP_PREFIX + "SetMessageDestructionProcessor",
             () -> delete(request.getDestroy(), mailboxSession)
                 .reduce(SetMessagesResponse.builder(),
                     SetMessagesResponse.Builder::accumulator,
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetMessagesMethod.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetMessagesMethod.java
index dd7b385..05ecc44 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetMessagesMethod.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetMessagesMethod.java
@@ -71,7 +71,7 @@ public class SetMessagesMethod implements Method {
             .addContext("destroy", setMessagesRequest.getDestroy())
             .addContext("ifInState", setMessagesRequest.getIfInState())
             .wrapArround(
-                () -> metricFactory.runPublishingTimerMetricLogP99(JMAP_PREFIX + METHOD_NAME.getName(),
+                () -> metricFactory.decorateSupplierWithTimerMetricLogP99(JMAP_PREFIX + METHOD_NAME.getName(),
                     () ->  Stream.of(
                         JmapResponse.builder().methodCallId(methodCallId)
                             .response(setMessagesResponse(setMessagesRequest, mailboxSession))
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetVacationResponseMethod.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetVacationResponseMethod.java
index 4da3a22..e8f2839 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetVacationResponseMethod.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetVacationResponseMethod.java
@@ -80,7 +80,7 @@ public class SetVacationResponseMethod implements Method {
         Preconditions.checkArgument(request instanceof SetVacationRequest);
         SetVacationRequest setVacationRequest = (SetVacationRequest) request;
 
-        return metricFactory.runPublishingTimerMetricLogP99(JMAP_PREFIX + METHOD_NAME.getName(),
+        return metricFactory.decorateSupplierWithTimerMetricLogP99(JMAP_PREFIX + METHOD_NAME.getName(),
             () -> process(methodCallId, mailboxSession, setVacationRequest)
                 .subscriberContext(jmapAction("SET_VACATION"))
                 .subscriberContext(context("set-vacation", MDCBuilder.of("update", setVacationRequest.getUpdate()))));
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/AuthenticationRoutes.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/AuthenticationRoutes.java
index 7b4a2c9..987ed7a 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/AuthenticationRoutes.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/AuthenticationRoutes.java
@@ -123,7 +123,7 @@ public class AuthenticationRoutes implements JMAPRoutes {
     }
 
     private Mono<Void> post(HttpServerRequest request, HttpServerResponse response) {
-        return Mono.from(metricFactory.runPublishingTimerMetricLogP99("JMAP-authentication-post",
+        return Mono.from(metricFactory.decoratePublisherWithTimerMetricLogP99("JMAP-authentication-post",
             Mono.just(request)
                 .map(this::assertJsonContentType)
                 .map(this::assertAcceptJsonOnly)
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/DefaultMailboxesProvisioner.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/DefaultMailboxesProvisioner.java
index 3252e95..6449ff0 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/DefaultMailboxesProvisioner.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/DefaultMailboxesProvisioner.java
@@ -61,7 +61,7 @@ class DefaultMailboxesProvisioner {
     }
 
     Mono<Void> createMailboxesIfNeeded(MailboxSession session) {
-        return metricFactory.runPublishingTimerMetric("JMAP-mailboxes-provisioning",
+        return metricFactory.decorateSupplierWithTimerMetric("JMAP-mailboxes-provisioning",
             () -> {
                 Username username = session.getUser();
                 return createDefaultMailboxes(username);
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/DownloadRoutes.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/DownloadRoutes.java
index 4291758..160beae 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/DownloadRoutes.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/DownloadRoutes.java
@@ -139,7 +139,7 @@ public class DownloadRoutes implements JMAPRoutes {
 
     private Mono<Void> post(HttpServerRequest request, HttpServerResponse response, DownloadPath downloadPath) {
         return authenticator.authenticate(request)
-            .flatMap(session -> Mono.from(metricFactory.runPublishingTimerMetric("JMAP-download-post",
+            .flatMap(session -> Mono.from(metricFactory.decoratePublisherWithTimerMetric("JMAP-download-post",
                     respondAttachmentAccessToken(session, downloadPath, response)))
                 .subscriberContext(jmapAuthContext(session)))
             .onErrorResume(UnauthorizedException.class, e -> handleAuthenticationFailure(response, LOGGER, e))
@@ -169,7 +169,7 @@ public class DownloadRoutes implements JMAPRoutes {
 
     private Mono<Void> get(HttpServerRequest request, HttpServerResponse response, DownloadPath downloadPath) {
         return authenticator.authenticate(request)
-            .flatMap(session -> Mono.from(metricFactory.runPublishingTimerMetric("JMAP-download-get",
+            .flatMap(session -> Mono.from(metricFactory.decoratePublisherWithTimerMetric("JMAP-download-get",
                     download(session, downloadPath, response)))
                 .subscriberContext(jmapAuthContext(session)))
             .onErrorResume(UnauthorizedException.class, e -> handleAuthenticationFailure(response, LOGGER, e))
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/JMAPApiRoutes.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/JMAPApiRoutes.java
index f723f5d..c33c0f3 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/JMAPApiRoutes.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/JMAPApiRoutes.java
@@ -99,7 +99,7 @@ public class JMAPApiRoutes implements JMAPRoutes {
             .flatMap(session -> Flux.merge(
                 userProvisioner.provisionUser(session),
                 defaultMailboxesProvisioner.createMailboxesIfNeeded(session))
-                .then(Mono.from(metricFactory.runPublishingTimerMetric("JMAP-request",
+                .then(Mono.from(metricFactory.decoratePublisherWithTimerMetric("JMAP-request",
                     post(request, response, session))))
                 .subscriberContext(jmapAuthContext(session)))
             .onErrorResume(BadRequestException.class, e -> handleBadRequest(response, LOGGER, e))
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/UploadRoutes.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/UploadRoutes.java
index 918ef92..9f7c235 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/UploadRoutes.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/UploadRoutes.java
@@ -115,7 +115,7 @@ public class UploadRoutes implements JMAPRoutes {
 
     private Mono<Void> post(HttpServerRequest request, HttpServerResponse response, ContentType contentType, MailboxSession session) {
         InputStream content = ReactorUtils.toInputStream(request.receive().asByteBuffer().subscribeOn(Schedulers.elastic()));
-        return Mono.from(metricFactory.runPublishingTimerMetric("JMAP-upload-post",
+        return Mono.from(metricFactory.decoratePublisherWithTimerMetric("JMAP-upload-post",
             handle(contentType, content, session, response)));
     }
 
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxGetMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxGetMethod.scala
index 5fb7d15..5b72d8f 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxGetMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxGetMethod.scala
@@ -32,7 +32,7 @@ import org.apache.james.mailbox.model.search.MailboxQuery
 import org.apache.james.mailbox.{MailboxManager, MailboxSession}
 import org.apache.james.metrics.api.MetricFactory
 import org.reactivestreams.Publisher
-import play.api.libs.json.{JsError, JsObject, JsSuccess, Json}
+import play.api.libs.json.{JsError, JsObject, JsSuccess}
 import reactor.core.scala.publisher.{SFlux, SMono}
 import reactor.core.scheduler.Schedulers
 
@@ -44,7 +44,7 @@ class MailboxGetMethod @Inject() (serializer: Serializer,
   override val methodName: MethodName = MethodName("Mailbox/get")
 
   override def process(invocation: Invocation, mailboxSession: MailboxSession): Publisher[Invocation] = {
-    metricFactory.runPublishingTimerMetricLogP99(JMAP_RFC8621_PREFIX + methodName.value,
+    metricFactory.decoratePublisherWithTimerMetricLogP99(JMAP_RFC8621_PREFIX + methodName.value,
       asMailboxGetRequest(invocation.arguments)
         .flatMap(mailboxGetRequest => getMailboxes(mailboxGetRequest, mailboxSession)
           .collectSeq()
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/http/Authenticator.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/http/Authenticator.java
index e3b47ad..49fb6f5 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/http/Authenticator.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/http/Authenticator.java
@@ -50,7 +50,7 @@ public class Authenticator {
     }
 
     public Mono<MailboxSession> authenticate(HttpServerRequest request) {
-        return Mono.from(metricFactory.runPublishingTimerMetric("JMAP-authentication-filter",
+        return Mono.from(metricFactory.decoratePublisherWithTimerMetric("JMAP-authentication-filter",
             Flux.fromIterable(authMethods)
                 .concatMap(auth -> auth.createMailboxSession(request))
                 .onErrorContinue((throwable, nothing) -> LOGGER.error("Error while trying to authenticate with JMAP", throwable))
diff --git a/third-party/spamassassin/src/main/java/org/apache/james/spamassassin/SpamAssassinInvoker.java b/third-party/spamassassin/src/main/java/org/apache/james/spamassassin/SpamAssassinInvoker.java
index bf3d4b7..12e82d7 100644
--- a/third-party/spamassassin/src/main/java/org/apache/james/spamassassin/SpamAssassinInvoker.java
+++ b/third-party/spamassassin/src/main/java/org/apache/james/spamassassin/SpamAssassinInvoker.java
@@ -94,7 +94,7 @@ public class SpamAssassinInvoker {
      *             if an error on scanning is detected
      */
     public SpamAssassinResult scanMail(MimeMessage message, Username username) throws MessagingException {
-        return metricFactory.runPublishingTimerMetric(
+        return metricFactory.decorateSupplierWithTimerMetric(
             "spamAssassin-check",
             Throwing.supplier(
                 () -> scanMailWithAdditionalHeaders(message,
@@ -103,7 +103,7 @@ public class SpamAssassinInvoker {
     }
 
     public SpamAssassinResult scanMail(MimeMessage message) throws MessagingException {
-        return metricFactory.runPublishingTimerMetric(
+        return metricFactory.decorateSupplierWithTimerMetric(
             "spamAssassin-check",
             Throwing.supplier(
                 () -> scanMailWithoutAdditionalHeaders(message))
@@ -194,7 +194,7 @@ public class SpamAssassinInvoker {
      *             if an error occured during learning.
      */
     public boolean learnAsSpam(InputStream message, Username username) throws MessagingException {
-        return metricFactory.runPublishingTimerMetric(
+        return metricFactory.decorateSupplierWithTimerMetric(
             "spamAssassin-spam-report",
             Throwing.supplier(
                 () -> reportMessageAs(message, username, MessageClass.SPAM))
@@ -210,7 +210,7 @@ public class SpamAssassinInvoker {
      *             if an error occured during learning.
      */
     public boolean learnAsHam(InputStream message, Username username) throws MessagingException {
-        return metricFactory.runPublishingTimerMetric(
+        return metricFactory.decorateSupplierWithTimerMetric(
             "spamAssassin-ham-report",
             Throwing.supplier(
                 () -> reportMessageAs(message, username, MessageClass.HAM))


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