Skip to content

Commit 47861e2

Browse files
crus-umichCaitlin Russell
andauthored
Decreasing default sleep time for refreshNow() calls, sleep time now … (#160)
*Issue #, if available:* #154 *Description of changes:* Decreased default sleep time for refreshNow() calls to be between 50 and 100 ms, also made this value configurable By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license. --------- Co-authored-by: Caitlin Russell <[email protected]>
1 parent 6a1e61d commit 47861e2

File tree

3 files changed

+81
-9
lines changed

3 files changed

+81
-9
lines changed

src/main/java/com/amazonaws/secretsmanager/caching/SecretCacheConfiguration.java

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ public class SecretCacheConfiguration {
3434
/** The default version stage to use when retrieving secret values. */
3535
public static final String DEFAULT_VERSION_STAGE = "AWSCURRENT";
3636

37+
/**
38+
* The default maximum jitter value in milliseconds to use when forcing a refresh.
39+
* This prevents continuous refreshNow() calls by adding a random sleep.
40+
*/
41+
public static final long DEFAULT_FORCE_REFRESH_JITTER = 100;
42+
3743
/** The client this cache instance will use for accessing AWS Secrets Manager. */
3844
private SecretsManagerClient client = null;
3945

@@ -60,6 +66,13 @@ public class SecretCacheConfiguration {
6066
*/
6167
private String versionStage = DEFAULT_VERSION_STAGE;
6268

69+
/**
70+
* When forcing a refresh using the refreshNow method, a random sleep
71+
* will be performed using this value. This helps prevent code from
72+
* executing a refreshNow in a continuous loop without waiting.
73+
*/
74+
private long forceRefreshJitterMillis = DEFAULT_FORCE_REFRESH_JITTER;
75+
6376
/**
6477
* Default constructor for the SecretCacheConfiguration object.
6578
*
@@ -237,4 +250,45 @@ public SecretCacheConfiguration withVersionStage(String versionStage) {
237250
return this;
238251
}
239252

253+
/**
254+
* Returns the refresh jitter that is used when force refreshing secrets.
255+
*
256+
* @return The maximum jitter sleep time in milliseconds used with refreshing secrets.
257+
*/
258+
public long getForceRefreshJitterMillis() {
259+
return this.forceRefreshJitterMillis;
260+
}
261+
262+
/**
263+
* Sets the maximum sleep time in milliseconds between force refresh calls.
264+
* This value is used to prevent continuous refreshNow() calls in tight loops
265+
* by adding a random sleep between half the configured value and the full value.
266+
* The value must be greater than or equal to zero.
267+
*
268+
* @param forceRefreshJitterMillis
269+
* The maximum sleep time in milliseconds between force refresh calls.
270+
* @throws IllegalArgumentException if the value is negative
271+
*/
272+
public void setForceRefreshJitterMillis(long forceRefreshJitterMillis) {
273+
if (forceRefreshJitterMillis < 0) {
274+
throw new IllegalArgumentException("Force refresh jitter must be greater than or equal to zero");
275+
}
276+
this.forceRefreshJitterMillis = forceRefreshJitterMillis;
277+
}
278+
279+
/**
280+
* Sets the maximum sleep time in milliseconds between force refresh calls.
281+
* This value is used to prevent continuous refreshNow() calls in tight loops
282+
* by adding a random sleep between half the configured value and the full value.
283+
*
284+
* @param forceRefreshJitterMillis
285+
* The maximum sleep time in milliseconds between force refresh calls.
286+
* @return The updated ClientConfiguration object with the new refresh sleep time.
287+
* @throws IllegalArgumentException if the value is negative
288+
*/
289+
public SecretCacheConfiguration withForceRefreshJitterMillis(long forceRefreshJitterMillis) {
290+
this.setForceRefreshJitterMillis(forceRefreshJitterMillis);
291+
return this;
292+
}
293+
240294
}

src/main/java/com/amazonaws/secretsmanager/caching/cache/SecretCacheObject.java

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,6 @@ public abstract class SecretCacheObject<T> {
3737
*/
3838
private static final long BACKOFF_PLATEAU = EXCEPTION_BACKOFF * 128;
3939

40-
/**
41-
* When forcing a refresh using the refreshNow method, a random sleep
42-
* will be performed using this value. This helps prevent code from
43-
* executing a refreshNow in a continuous loop without waiting.
44-
*/
45-
private static final long FORCE_REFRESH_JITTER_SLEEP = 5000;
46-
4740
/** The secret identifier for this cached object. */
4841
protected final String secretId;
4942

@@ -215,10 +208,11 @@ public boolean refreshNow() throws InterruptedException {
215208
// When forcing a refresh, always sleep with a random jitter
216209
// to prevent coding errors that could be calling refreshNow
217210
// in a loop.
211+
long jitter = this.config.getForceRefreshJitterMillis();
218212
long sleep = ThreadLocalRandom.current()
219213
.nextLong(
220-
FORCE_REFRESH_JITTER_SLEEP / 2,
221-
FORCE_REFRESH_JITTER_SLEEP + 1);
214+
jitter / 2,
215+
jitter + 1);
222216
// Make sure we are not waiting for the next refresh after an
223217
// exception. If we are, sleep based on the retry delay of
224218
// the refresh to prevent a hard loop in attempting to refresh a

src/test/java/com/amazonaws/secretsmanager/caching/SecretCacheTest.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,30 @@ public void secretCacheConstructorTest() {
8383
} catch (Exception e) {
8484
}
8585
}
86+
87+
@Test
88+
public void testForceRefreshJitterConfiguration() {
89+
// Test default value
90+
SecretCacheConfiguration config = new SecretCacheConfiguration();
91+
Assert.assertEquals(config.getForceRefreshJitterMillis(), SecretCacheConfiguration.DEFAULT_FORCE_REFRESH_JITTER);
92+
93+
// Test setting a custom value
94+
long customJitter = 250L;
95+
config.setForceRefreshJitterMillis(customJitter);
96+
Assert.assertEquals(config.getForceRefreshJitterMillis(), customJitter);
97+
98+
// Test zero is valid
99+
config.setForceRefreshJitterMillis(0);
100+
Assert.assertEquals(config.getForceRefreshJitterMillis(), 0);
101+
}
102+
103+
@Test(expectedExceptions = IllegalArgumentException.class,
104+
expectedExceptionsMessageRegExp = "Force refresh jitter must be greater than or equal to zero")
105+
public void testForceRefreshJitterValidation() {
106+
// Test that negative values throw an exception
107+
SecretCacheConfiguration config = new SecretCacheConfiguration();
108+
config.setForceRefreshJitterMillis(-1);
109+
}
86110

87111
@Test
88112
public void basicSecretCacheTest() {

0 commit comments

Comments
 (0)