private static Task <ExceptionTarget> GetOrAddStringCachedExecptionTargetAsync(string input, ExceptionTarget target = null) { ExceptionTarget exTarget = null; if (_stringExceptionCache.ContainsKey(input)) { exTarget = _stringExceptionCache[input]; } else if (target is null) { exTarget = new ExceptionTarget { AllowConsecutiveFailure = true, FailureCount = 0, FailureCountMax = 5, GuaranteeFailure = false }; _stringExceptionCache[input] = exTarget; } else { _stringExceptionCache[input] = exTarget = target; } return(Task.FromResult(exTarget)); }
public static async Task RollsTheDiceAsync(object input, ExceptionTarget target = null) { switch (input) { case int userInput: await HandleIntAsync(userInput, target).ConfigureAwait(false); break; case long userInput: await HandleLongAsync(userInput, target).ConfigureAwait(false); break; case string userInput: await HandleStringAsync(userInput, target).ConfigureAwait(false); break; } }
private static async Task HandleIntAsync(int input, ExceptionTarget target = null, bool allowContextualCleanup = false) { var exTarget = await GetOrAddIntCachedExecptionTargetAsync(input, target).ConfigureAwait(false); if (exTarget.FailureCount < exTarget.FailureCountMax) { var throwException = false; // Can We Throw Exception? if (exTarget.GuaranteeFailure || exTarget.AllowConsecutiveFailure || (!exTarget.AllowConsecutiveFailure && !exTarget.LastIterationFailed)) { // Will We Throw Exception? throwException = await ShouldWeThrowExceptionAsync(input).ConfigureAwait(false); if (throwException) // The Math Gods Say Yes! { exTarget.FailureCount++; exTarget.LastIterationFailed = true; } else { exTarget.LastIterationFailed = false; } } else { exTarget.LastIterationFailed = false; } // Update Cache _intExceptionCache[input] = exTarget; if (throwException) { await ThrowsRandomExceptionAsync().ConfigureAwait(false); } } else if (allowContextualCleanup) // We are finished with this input! Allows it come back in! { _intExceptionCache.TryRemove(input, out ExceptionTarget outTarget); } }