@@ -50,11 +50,11 @@ public class DefaultCredentialsRefreshService implements CredentialsRefreshServi
5050
5151 private final boolean privateScheduler ;
5252
53- private final Function <Duration , Long > refreshDelayStrategy ;
53+ private final Function <Duration , Duration > refreshDelayStrategy ;
5454
5555 private final Function <Duration , Boolean > needRefreshStrategy ;
5656
57- public DefaultCredentialsRefreshService (ScheduledExecutorService scheduler , Function <Duration , Long > refreshDelayStrategy , Function <Duration , Boolean > needRefreshStrategy ) {
57+ public DefaultCredentialsRefreshService (ScheduledExecutorService scheduler , Function <Duration , Duration > refreshDelayStrategy , Function <Duration , Boolean > needRefreshStrategy ) {
5858 this .refreshDelayStrategy = refreshDelayStrategy ;
5959 this .needRefreshStrategy = needRefreshStrategy ;
6060 if (scheduler == null ) {
@@ -67,43 +67,57 @@ public DefaultCredentialsRefreshService(ScheduledExecutorService scheduler, Func
6767 }
6868
6969 /**
70- * Delay before refresh is <code>TTL - specified duration</code> .
70+ * Delay before refresh is a ratio of the time before expiration .
7171 * <p>
72- * E.g. if TTL is 60 seconds and specified duration is 20 seconds, refresh will
72+ * E.g. if time before expiration is 60 seconds and specified ratio is 0.8, refresh will
73+ * be scheduled in 60 x 0.8 = 48 seconds.
74+ *
75+ * @param ratio
76+ * @return the delay before refreshing
77+ */
78+ public static Function <Duration , Duration > ratioRefreshDelayStrategy (double ratio ) {
79+ return new RatioRefreshDelayStrategy (ratio );
80+ }
81+
82+ /**
83+ * Delay before refresh is <code>time before expiration - specified duration</code>.
84+ * <p>
85+ * E.g. if time before expiration is 60 seconds and specified duration is 20 seconds, refresh will
7386 * be scheduled in 60 - 20 = 40 seconds.
7487 *
7588 * @param duration
76- * @return
89+ * @return the delay before refreshing
7790 */
78- public static Function <Duration , Long > fixedDelayBeforeExpirationRefreshDelayStrategy (Duration duration ) {
79- return new FixedDelayBeforeExpirationRefreshDelayStrategy (duration . toMillis () );
91+ public static Function <Duration , Duration > fixedDelayBeforeExpirationRefreshDelayStrategy (Duration duration ) {
92+ return new FixedDelayBeforeExpirationRefreshDelayStrategy (duration );
8093 }
8194
8295 /**
8396 * Advise to refresh credentials if <code>TTL <= limit</code>.
8497 *
8598 * @param limitBeforeExpiration
86- * @return
99+ * @return true if credentials should be refreshed, false otherwise
87100 */
88101 public static Function <Duration , Boolean > fixedTimeNeedRefreshStrategy (Duration limitBeforeExpiration ) {
89102 return new FixedTimeNeedRefreshStrategy (limitBeforeExpiration .toMillis ());
90103 }
91104
92- // TODO add a delay refresh strategy that bases the time on a percentage of the TTL, use it as default with 80% TTL
93-
94105 private static Runnable refresh (ScheduledExecutorService scheduler , CredentialsProviderState credentialsProviderState ,
95- Function <Duration , Long > refreshDelayStrategy ) {
106+ Function <Duration , Duration > refreshDelayStrategy ) {
96107 return () -> {
97108 LOGGER .debug ("Refreshing token" );
98109 credentialsProviderState .refresh ();
99110
100111 Duration timeBeforeExpiration = credentialsProviderState .credentialsProvider .getTimeBeforeExpiration ();
112+ Duration newDelay = refreshDelayStrategy .apply (timeBeforeExpiration );
101113
102- long newDelay = refreshDelayStrategy . apply ( timeBeforeExpiration );
114+ LOGGER . debug ( "Scheduling refresh in {} seconds" , newDelay . getSeconds () );
103115
104- LOGGER .debug ("Scheduling refresh in {} milliseconds" , newDelay );
105-
106- ScheduledFuture <?> scheduledFuture = scheduler .schedule (refresh (scheduler , credentialsProviderState , refreshDelayStrategy ), newDelay , TimeUnit .MILLISECONDS );
116+ ScheduledFuture <?> scheduledFuture = scheduler .schedule (
117+ refresh (scheduler , credentialsProviderState , refreshDelayStrategy ),
118+ newDelay .getSeconds (),
119+ TimeUnit .SECONDS
120+ );
107121 credentialsProviderState .refreshTask .set (scheduledFuture );
108122 };
109123 }
@@ -122,9 +136,13 @@ public String register(CredentialsProvider credentialsProvider, Callable<Boolean
122136 credentialsProviderState .add (registration );
123137
124138 credentialsProviderState .maybeSetRefreshTask (() -> {
125- long delay = refreshDelayStrategy .apply (credentialsProvider .getTimeBeforeExpiration ());
126- LOGGER .debug ("Scheduling refresh in {} milliseconds" , delay );
127- return scheduler .schedule (refresh (scheduler , credentialsProviderState , refreshDelayStrategy ), delay , TimeUnit .MILLISECONDS );
139+ Duration delay = refreshDelayStrategy .apply (credentialsProvider .getTimeBeforeExpiration ());
140+ LOGGER .debug ("Scheduling refresh in {} seconds" , delay .getSeconds ());
141+ return scheduler .schedule (
142+ refresh (scheduler , credentialsProviderState , refreshDelayStrategy ),
143+ delay .getSeconds (),
144+ TimeUnit .SECONDS
145+ );
128146 });
129147
130148 return registrationId ;
@@ -163,25 +181,42 @@ public Boolean apply(Duration timeBeforeExpiration) {
163181 }
164182 }
165183
166- private static class FixedDelayBeforeExpirationRefreshDelayStrategy implements Function <Duration , Long > {
184+ private static class FixedDelayBeforeExpirationRefreshDelayStrategy implements Function <Duration , Duration > {
167185
168- private final long delay ;
186+ private final Duration delay ;
169187
170- private FixedDelayBeforeExpirationRefreshDelayStrategy (long delay ) {
188+ private FixedDelayBeforeExpirationRefreshDelayStrategy (Duration delay ) {
171189 this .delay = delay ;
172190 }
173191
174192 @ Override
175- public Long apply (Duration timeBeforeExpiration ) {
176- long refreshTimeBeforeExpiration = timeBeforeExpiration .toMillis () - delay ;
177- if (refreshTimeBeforeExpiration < 0 ) {
178- return timeBeforeExpiration . toMillis () ;
193+ public Duration apply (Duration timeBeforeExpiration ) {
194+ Duration refreshTimeBeforeExpiration = timeBeforeExpiration .minus ( delay ) ;
195+ if (refreshTimeBeforeExpiration . isNegative () ) {
196+ return timeBeforeExpiration ;
179197 } else {
180198 return refreshTimeBeforeExpiration ;
181199 }
182200 }
183201 }
184202
203+ private static class RatioRefreshDelayStrategy implements Function <Duration , Duration > {
204+
205+ private final double ratio ;
206+
207+ private RatioRefreshDelayStrategy (double ratio ) {
208+ if (ratio < 0 || ratio > 1 ) {
209+ throw new IllegalArgumentException ("Ratio should be > 0 and <= 1: " + ratio );
210+ }
211+ this .ratio = ratio ;
212+ }
213+
214+ @ Override
215+ public Duration apply (Duration duration ) {
216+ return Duration .ofSeconds ((long ) ((double ) duration .getSeconds () * ratio ));
217+ }
218+ }
219+
185220 static class Registration {
186221
187222 private final Callable <Boolean > refreshAction ;
@@ -240,7 +275,7 @@ void maybeSetRefreshTask(Supplier<ScheduledFuture<?>> scheduledFutureSupplier) {
240275 }
241276
242277 void refresh () {
243- // FIXME check whether thread has been cancelled or not before refresh() and registratAction .call()
278+ // FIXME check whether thread has been cancelled or not before refresh() and refreshAction .call()
244279
245280 // FIXME protect this call, or at least log some error
246281 this .credentialsProvider .refresh ();
@@ -276,16 +311,16 @@ public static class DefaultCredentialsRefreshServiceBuilder {
276311
277312 private ScheduledExecutorService scheduler ;
278313
279- private Function <Duration , Long > refreshDelayStrategy = fixedDelayBeforeExpirationRefreshDelayStrategy ( Duration . ofSeconds ( 60 ) );
314+ private Function <Duration , Duration > refreshDelayStrategy = ratioRefreshDelayStrategy ( 0.8 );
280315
281- private Function <Duration , Boolean > needRefreshStrategy = fixedTimeNeedRefreshStrategy ( Duration . ofSeconds ( 60 )) ;
316+ private Function <Duration , Boolean > needRefreshStrategy = ttl -> false ;
282317
283318 public DefaultCredentialsRefreshServiceBuilder scheduler (ScheduledThreadPoolExecutor scheduler ) {
284319 this .scheduler = scheduler ;
285320 return this ;
286321 }
287322
288- public DefaultCredentialsRefreshServiceBuilder refreshDelayStrategy (Function <Duration , Long > refreshDelayStrategy ) {
323+ public DefaultCredentialsRefreshServiceBuilder refreshDelayStrategy (Function <Duration , Duration > refreshDelayStrategy ) {
289324 this .refreshDelayStrategy = refreshDelayStrategy ;
290325 return this ;
291326 }
0 commit comments