/// <summary> /// Method to force the refresh of a cached secret state. /// Returns true if the refresh completed without error. /// </summary> public async Task <bool> RefreshNowAsync() { refreshNeeded = true; // When forcing a refresh, always sleep with a random jitter // to prevent coding errors that could be calling refreshNow // in a loop. long sleep = FORCE_REFRESH_JITTERED_DELAY.GetRetryDelay(1).Milliseconds; // Make sure we are not waiting for the next refresh after an // exception. If we are, sleep based on the retry delay of // the refresh to prevent a hard loop in attempting to refresh a // secret that continues to throw an exception such as AccessDenied. if (null != exception) { long wait = nextRetryTime - Environment.TickCount; sleep = Math.Max(wait, sleep); } Thread.Sleep((int)sleep); // Perform the requested refresh. bool success = false; await Lock.WaitAsync(); try { success = await RefreshAsync(); } finally { Lock.Release(); } return(null == exception && success); }
/// <summary> /// Refresh the cached secret state only when needed. /// </summary> private async Task <bool> RefreshAsync() { if (!IsRefreshNeeded()) { return(false); } refreshNeeded = false; try { SetResult(await ExecuteRefreshAsync()); exception = null; exceptionCount = 0; return(true); } catch (Exception ex) when(ex is AmazonServiceException || ex is AmazonClientException) { exception = ex; // Determine the amount of growth in exception backoff time based on the growth // factor and default backoff duration. nextRetryTime = Environment.TickCount + EXCEPTION_JITTERED_DELAY.GetRetryDelay((int)exceptionCount).Milliseconds; } return(false); }