SLING-5570 - use exponential backoff in retries

git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1732912 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/main/java/org/apache/sling/testing/teleporter/client/ExponentialBackoffDelay.java b/src/main/java/org/apache/sling/testing/teleporter/client/ExponentialBackoffDelay.java
new file mode 100644
index 0000000..e902842
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/teleporter/client/ExponentialBackoffDelay.java
@@ -0,0 +1,43 @@
+/*
+ * 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.sling.testing.teleporter.client;
+
+/** Wait with exponential backoff, for retries */ 
+public class ExponentialBackoffDelay {
+    public static final float INCREASE_RATE = 1.2f;
+    private int currentDelay;
+    private final int endDelay;
+    
+    public ExponentialBackoffDelay(int startDelayMsec, int endDelayMsec) {
+        currentDelay = startDelayMsec;
+        endDelay = endDelayMsec;
+    }
+    
+    public int getNextDelayMsec() {
+        final int result = currentDelay;
+        currentDelay = Math.min(endDelay, (int)(currentDelay * INCREASE_RATE));
+        return result;
+    }
+    
+    public void waitNextDelay() {
+        try {
+            final int toWait = getNextDelayMsec();
+            Thread.sleep(toWait);
+        } catch(InterruptedException ignored) {
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/testing/teleporter/client/TeleporterHttpClient.java b/src/main/java/org/apache/sling/testing/teleporter/client/TeleporterHttpClient.java
index dc176c9..e805e45 100644
--- a/src/main/java/org/apache/sling/testing/teleporter/client/TeleporterHttpClient.java
+++ b/src/main/java/org/apache/sling/testing/teleporter/client/TeleporterHttpClient.java
@@ -69,6 +69,7 @@
     public void waitForStatus(String url, int expectedStatus, int timeoutMsec) throws IOException {
         final long end = System.currentTimeMillis() + timeoutMsec;
         final Set<Integer> statusSet = new HashSet<Integer>();
+        final ExponentialBackoffDelay d = new ExponentialBackoffDelay(50,  250);
         while(System.currentTimeMillis() < end) {
             try {
                 final int status = getHttpGetStatus(url);
@@ -76,7 +77,7 @@
                 if(status == expectedStatus) {
                     return;
                 }
-                Thread.sleep(50);
+                d.waitNextDelay();
             } catch(Exception ignore) {
             }
         }
@@ -147,6 +148,7 @@
         
         // Wait for non-404 response that signals that test bundle is ready
         final long timeout = System.currentTimeMillis() + (testReadyTimeoutSeconds * 1000L);
+        final ExponentialBackoffDelay delay = new ExponentialBackoffDelay(25, 1000);
         while(true) {
             if(getHttpGetStatus(testUrl) == 200) {
                 break;
@@ -155,6 +157,7 @@
                 fail("Timeout waiting for test at " + testUrl + " (" + testReadyTimeoutSeconds + " seconds)");
                 break;
             }
+            delay.waitNextDelay();
         }
         
         final HttpURLConnection c = (HttpURLConnection)new URL(testUrl).openConnection();
diff --git a/src/test/java/org/apache/sling/testing/teleporter/client/ExponentialBackoffDelayTest.java b/src/test/java/org/apache/sling/testing/teleporter/client/ExponentialBackoffDelayTest.java
new file mode 100644
index 0000000..acec7f9
--- /dev/null
+++ b/src/test/java/org/apache/sling/testing/teleporter/client/ExponentialBackoffDelayTest.java
@@ -0,0 +1,45 @@
+/*
+ * 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.sling.testing.teleporter.client;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+public class ExponentialBackoffDelayTest {
+    @Test 
+    public void testDelaySequence() {
+        final ExponentialBackoffDelay d = new ExponentialBackoffDelay(25, 100);
+        final int [] expected = {
+                25,
+                30,
+                36,
+                43,
+                51,
+                61,
+                73,
+                87,
+                100,
+                100,
+                100
+        };
+        
+        for(int exp : expected) {
+            assertEquals(exp, d.getNextDelayMsec());
+        }
+    } 
+}
\ No newline at end of file