Skip to content
Browse files

varieties of counting retries

  • Loading branch information...
1 parent bc59dde commit 2d7376260b3242b3111d4dc9c1535dd4059b24cf @n8han n8han committed
Showing with 65 additions and 32 deletions.
  1. +0 −32 core/src/main/scala/retry/Times.scala
  2. +65 −0 core/src/main/scala/retry/retries.scala
View
32 core/src/main/scala/retry/Times.scala
@@ -1,32 +0,0 @@
-package dispatch.retry
-
-import dispatch._
-
-object Directly {
- def apply[T](count: Int)(promise: Promise[T])
- (implicit success: Success[T]): Promise[T] = {
- promise.flatMap { res =>
- if (count < 1 || success.predicate(res)) promise
- else Directly(count - 1)(promise.replay)
- }
- }
-}
-
-object Pause {
- def apply[T](count: Int, delay: Duration)(promise: Promise[T])
- (implicit success: Success[T]): Promise[T] = {
- promise.flatMap { res =>
- if (count < 1 || success.predicate(res)) promise
- else promise.http.promise.sleep(delay) {
- Pause(count - 1, delay)(promise.replay)
- }.flatten
- }
- }
-}
-
-class Success[T](val predicate: T => Boolean)
-
-object Success {
- implicit def either[A,B]: Success[Either[A,B]] =
- new Success(_.isRight)
-}
View
65 core/src/main/scala/retry/retries.scala
@@ -0,0 +1,65 @@
+package dispatch.retry
+
+import java.util.concurrent.TimeUnit
+
+import dispatch._
+
+/** Retry immediately after failure */
+object Directly extends CountingRetry {
+ def apply[T](max: Int = 3)(promise: Promise[T])
+ (implicit success: Success[T]): Promise[T] = {
+ retry(max, promise, success, Directly(_)(promise.replay))
+ }
+}
+
+/** Retry with a pause between attempts */
+object Pause extends CountingRetry {
+ def apply[T](max: Int = 4,
+ delay: Duration = Duration(500, TimeUnit.MILLISECONDS))
+ (promise: Promise[T])
+ (implicit success: Success[T]): Promise[T] = {
+ retry(max,
+ promise,
+ success,
+ c => promise.http.promise.sleep(delay) {
+ Pause(c, delay)(promise.replay)
+ }.flatten)
+ }
+}
+
+/** Retry with exponential backoff */
+object Backoff extends CountingRetry {
+ def apply[T](max: Int = 8,
+ delay: Duration = Duration(500, TimeUnit.MILLISECONDS),
+ base: Int = 2)
+ (promise: Promise[T])
+ (implicit success: Success[T]): Promise[T] = {
+ retry(max,
+ promise,
+ success,
+ count => promise.http.promise.sleep(delay) {
+ Backoff(count,
+ Duration(delay.length * base, delay.unit),
+ base)(promise.replay)
+ }.flatten)
+ }
+}
+
+class Success[T](val predicate: T => Boolean)
+
+object Success {
+ implicit def either[A,B]: Success[Either[A,B]] =
+ new Success(_.isRight)
+}
+
+trait CountingRetry {
+ protected def retry[T](max: Int,
+ promise: Promise[T],
+ success: Success[T],
+ orElse: Int => Promise[T]
+ ) =
+ promise.flatMap { res =>
+ if (max < 1 || success.predicate(res)) promise
+ else orElse(max - 1)
+ }
+}

0 comments on commit 2d73762

Please sign in to comment.
Something went wrong with that request. Please try again.