@@ -3,16 +3,29 @@ package retry
3
3
import odelay .{ Delay , Timer }
4
4
import scala .concurrent .{ Future , ExecutionContext }
5
5
import scala .concurrent .duration .{ Duration , FiniteDuration }
6
+ import scala .language .implicitConversions
6
7
import scala .util .control .NonFatal
7
8
import java .util .concurrent .TimeUnit
8
9
10
+ // This case class and its implicit conversions allow us to accept both
11
+ // `() => Future[T]` and `Future[T]`-by-name as Policy.apply arguments.
12
+ // Note that these two types are the same after erasure.
13
+ case class PromiseWrapper [T ](
14
+ promise : () => Future [T ]
15
+ )
16
+
17
+ object PromiseWrapper {
18
+ implicit def fromFuture [T ](promise : () => Future [T ]): PromiseWrapper [T ] = PromiseWrapper (promise)
19
+ implicit def toFuture [T ](pw : PromiseWrapper [T ]): () => Future [T ] = pw.promise
20
+ }
21
+
9
22
object Directly {
10
23
11
24
/** Retry immediately after failure forever */
12
25
def forever : Policy =
13
26
new Policy {
14
27
def apply [T ]
15
- (promise : () => Future [T ])
28
+ (promise : PromiseWrapper [T ])
16
29
(implicit success : Success [T ],
17
30
executor : ExecutionContext ): Future [T ] =
18
31
retry(promise, promise)
@@ -22,7 +35,7 @@ object Directly {
22
35
def apply (max : Int = 3 ): Policy =
23
36
new CountingPolicy {
24
37
def apply [T ]
25
- (promise : () => Future [T ])
38
+ (promise : PromiseWrapper [T ])
26
39
(implicit success : Success [T ],
27
40
executor : ExecutionContext ): Future [T ] = {
28
41
def run (max : Int ): Future [T ] = countdown(max, promise, run)
@@ -39,7 +52,7 @@ object Pause {
39
52
(implicit timer : Timer ): Policy =
40
53
new Policy { self =>
41
54
def apply [T ]
42
- (promise : () => Future [T ])
55
+ (promise : PromiseWrapper [T ])
43
56
(implicit success : Success [T ],
44
57
executor : ExecutionContext ): Future [T ] =
45
58
retry(promise, { () =>
@@ -52,7 +65,7 @@ object Pause {
52
65
(implicit timer : Timer ): Policy =
53
66
new CountingPolicy {
54
67
def apply [T ]
55
- (promise : () => Future [T ])
68
+ (promise : PromiseWrapper [T ])
56
69
(implicit success : Success [T ],
57
70
executor : ExecutionContext ): Future [T ] = {
58
71
def run (max : Int ): Future [T ] = countdown(
@@ -70,7 +83,7 @@ object Backoff {
70
83
(implicit timer : Timer ): Policy =
71
84
new Policy {
72
85
def apply [T ]
73
- (promise : () => Future [T ])
86
+ (promise : PromiseWrapper [T ])
74
87
(implicit success : Success [T ],
75
88
executor : ExecutionContext ): Future [T ] = {
76
89
def run (delay : FiniteDuration ): Future [T ] = retry(promise, { () =>
@@ -90,7 +103,7 @@ object Backoff {
90
103
(implicit timer : Timer ): Policy =
91
104
new CountingPolicy {
92
105
def apply [T ]
93
- (promise : () => Future [T ])
106
+ (promise : PromiseWrapper [T ])
94
107
(implicit success : Success [T ],
95
108
executor : ExecutionContext ): Future [T ] = {
96
109
def run (max : Int , delay : FiniteDuration ): Future [T ] = countdown(
@@ -121,7 +134,7 @@ object When {
121
134
type Depends = PartialFunction [Any , Policy ]
122
135
def apply (depends : Depends ): Policy =
123
136
new Policy {
124
- def apply [T ](promise : () => Future [T ])
137
+ def apply [T ](promise : PromiseWrapper [T ])
125
138
(implicit success : Success [T ],
126
139
executor : ExecutionContext ): Future [T ] = {
127
140
val fut = promise()
@@ -157,10 +170,16 @@ trait CountingPolicy extends Policy {
157
170
* specific to implementations
158
171
*/
159
172
trait Policy {
160
- def apply [T ](promise : () => Future [T ])
173
+
174
+ def apply [T ](pw : PromiseWrapper [T ])
161
175
(implicit success : Success [T ],
162
176
executor : ExecutionContext ): Future [T ]
163
177
178
+ def apply [T ](promise : => Future [T ])
179
+ (implicit success : Success [T ],
180
+ executor : ExecutionContext ): Future [T ] =
181
+ apply { () => promise }
182
+
164
183
protected def retry [T ](
165
184
promise : () => Future [T ],
166
185
orElse : () => Future [T ],
0 commit comments