Repository: james-project
Updated Branches:
  refs/heads/master 4cdfef08a -> 1f390f4f3


MAILBOX-372 generating wait delay in WaitDelayGenerator


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/bd656cf8
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/bd656cf8
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/bd656cf8

Branch: refs/heads/master
Commit: bd656cf888086b4bfb6caae401746287f2e8eedc
Parents: 2c60acb
Author: tran tien duc <dt...@linagora.com>
Authored: Tue Jan 15 14:56:03 2019 +0700
Committer: tran tien duc <dt...@linagora.com>
Committed: Wed Jan 16 14:07:50 2019 +0700

----------------------------------------------------------------------
 .../mailbox/events/WaitDelayGenerator.java      | 71 ++++++++++++++++++++
 .../mailbox/events/WaitDelayGeneratorTest.java  | 58 ++++++++++++++++
 2 files changed, 129 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/bd656cf8/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/WaitDelayGenerator.java
----------------------------------------------------------------------
diff --git 
a/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/WaitDelayGenerator.java
 
b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/WaitDelayGenerator.java
new file mode 100644
index 0000000..fdcf9cc
--- /dev/null
+++ 
b/mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/WaitDelayGenerator.java
@@ -0,0 +1,71 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.mailbox.events;
+
+import java.security.SecureRandom;
+import java.time.Duration;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+
+import reactor.core.publisher.Mono;
+
+class WaitDelayGenerator {
+
+    static WaitDelayGenerator of(RetryBackoff retryBackoff) {
+        return new WaitDelayGenerator(retryBackoff);
+    }
+
+    private static int randomBetween(int lowest, int highest) {
+        Preconditions.checkArgument(lowest <= highest, "lowest always has to 
be less than or equals highest");
+        return SECURE_RANDOM.nextInt(highest - lowest) + lowest;
+    }
+
+    private static final SecureRandom SECURE_RANDOM = new SecureRandom();
+
+    private final RetryBackoff retryBackoff;
+
+    private WaitDelayGenerator(RetryBackoff retryBackoff) {
+        this.retryBackoff = retryBackoff;
+    }
+
+    Mono<Integer> delayIfHaveTo(int retryCount) {
+        Mono<Integer> countRetryMono = Mono.just(retryCount);
+        if (retryCount < 1) {
+            return countRetryMono;
+        }
+
+        return countRetryMono
+            .filter(count -> count <= retryBackoff.getMaxRetries())
+            .delayElement(generateDelay(retryCount));
+    }
+
+    @VisibleForTesting
+    Duration generateDelay(int retryCount) {
+        if (retryCount < 1) {
+            return Duration.ZERO;
+        }
+        int exponentialFactor = Double.valueOf(Math.pow(2, retryCount - 
1)).intValue();
+        int minDelay = exponentialFactor * (int) 
retryBackoff.getFirstBackoff().toMillis();
+        int maxDelay = Double.valueOf(minDelay + minDelay * 
retryBackoff.getJitterFactor()).intValue();
+
+        return Duration.ofMillis(randomBetween(minDelay, maxDelay));
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bd656cf8/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/WaitDelayGeneratorTest.java
----------------------------------------------------------------------
diff --git 
a/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/WaitDelayGeneratorTest.java
 
b/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/WaitDelayGeneratorTest.java
new file mode 100644
index 0000000..acc3a9f
--- /dev/null
+++ 
b/mailbox/event/event-rabbitmq/src/test/java/org/apache/james/mailbox/events/WaitDelayGeneratorTest.java
@@ -0,0 +1,58 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.mailbox.events;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.time.Duration;
+
+import org.assertj.core.api.SoftAssertions;
+import org.junit.jupiter.api.Test;
+
+class WaitDelayGeneratorTest {
+
+    @Test
+    void generateDelayShouldReturnZeroWhenZeroRetryCount() {
+        WaitDelayGenerator generator = 
WaitDelayGenerator.of(RetryBackoff.defaultRetryBackoff());
+
+        assertThat(generator.generateDelay(0))
+            .isEqualTo(Duration.ofMillis(0));
+    }
+
+    @Test
+    void 
generateDelayShouldReturnByRandomInRangeOfExponentialGrowthOfRetryCount() {
+        WaitDelayGenerator generator = 
WaitDelayGenerator.of(RetryBackoff.builder()
+            .maxRetries(4)
+            .firstBackoff(Duration.ofMillis(100))
+            .jitterFactor(0.5)
+            .build());
+
+        SoftAssertions.assertSoftly(softly -> {
+            softly.assertThat(generator.generateDelay(1).toMillis())
+                .isBetween(100L, 150L);
+            softly.assertThat(generator.generateDelay(2).toMillis())
+                .isBetween(200L, 300L);
+            softly.assertThat(generator.generateDelay(3).toMillis())
+                .isBetween(400L, 600L);
+            softly.assertThat(generator.generateDelay(4).toMillis())
+                .isBetween(800L, 1200L);
+        });
+    }
+}
\ No newline at end of file


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

Reply via email to