private static void Sleep(RetryExceptionHandler handler, IDictionary <string, object> callContextDictionary, SleepHandler sleepHandler) { if (handler.IsDelayBased) { sleepHandler(handler.DelayTimeSpan); } else { try { IExpression expression = Expression.Parse(handler.DelayRateExpression); object result = expression.GetValue(null, callContextDictionary); decimal d = decimal.Parse(result.ToString()); decimal rounded = decimal.Round(d * 1000, 0); TimeSpan duration = TimeSpan.FromMilliseconds(decimal.ToDouble(rounded)); sleepHandler(duration); } catch (InvalidCastException e) { log.Warn("Was not able to cast expression to decimal [" + handler.DelayRateExpression + "]. Sleeping for 1 second", e); sleepHandler(new TimeSpan(0, 0, 1)); } catch (Exception e) { log.Warn("Was not able to evaluate rate expression [" + handler.DelayRateExpression + "]. Sleeping for 1 second", e); sleepHandler(new TimeSpan(0, 0, 1)); } } }
/// <summary> /// Invoked by an <see cref="Oragon.Spring.Objects.Factory.IObjectFactory"/> /// after it has injected all of an object's dependencies. /// </summary> /// <remarks> /// <p> /// This method allows the object instance to perform the kind of /// initialization only possible when all of it's dependencies have /// been injected (set), and to throw an appropriate exception in the /// event of misconfiguration. /// </p> /// <p> /// Please do consult the class level documentation for the /// <see cref="Oragon.Spring.Objects.Factory.IObjectFactory"/> interface for a /// description of exactly <i>when</i> this method is invoked. In /// particular, it is worth noting that the /// <see cref="Oragon.Spring.Objects.Factory.IObjectFactoryAware"/> /// and <see cref="Oragon.Spring.Context.IApplicationContextAware"/> /// callbacks will have been invoked <i>prior</i> to this method being /// called. /// </p> /// </remarks> /// <exception cref="System.Exception"> /// In the event of misconfiguration (such as the failure to set a /// required property) or if initialization fails. /// </exception> public override void AfterPropertiesSet() { if (retryExpression == null) { throw new ArgumentException("Must specify retry expression."); } RetryExceptionHandler handler = Parse(retryExpression); if (handler == null) { throw new ArgumentException("Was not able to parse retry expression string [" + retryExpression + "]"); } retryExceptionHandler = handler; }
/// <summary> /// Parses the specified handler string. /// </summary> /// <param name="retryExpressionString">The handler string.</param> /// <returns></returns> protected virtual RetryExceptionHandler Parse(string retryExpressionString) { ParsedAdviceExpression parsedAdviceExpression = ParseAdviceExpression(retryExpressionString); if (!parsedAdviceExpression.Success) { log.Warn("Could not parse retry expression " + retryExpressionString); return(null); } RetryExceptionHandler handler = new RetryExceptionHandler(parsedAdviceExpression.ExceptionNames); handler.ConstraintExpressionText = parsedAdviceExpression.ConstraintExpression; handler.ActionExpressionText = parsedAdviceExpression.AdviceExpression; Match match = GetMatchForActionExpression(parsedAdviceExpression.ActionExpressionText, delayRegex); if (match.Success) { handler.MaximumRetryCount = int.Parse(match.Groups[1].Value.Trim()); handler.IsDelayBased = true; try { string ts = match.Groups[3].Value.Trim(); handler.DelayTimeSpan = (TimeSpan)timeSpanConverter.ConvertFrom(null, null, ts); } catch (Exception) { log.Warn("Could not parse timespan " + match.Groups[3].Value.Trim()); return(null); } return(handler); } else { match = GetMatchForActionExpression(parsedAdviceExpression.ActionExpressionText, rateRegex); if (match.Success) { handler.MaximumRetryCount = int.Parse(match.Groups[1].Value.Trim()); handler.IsDelayBased = false; handler.DelayRateExpression = match.Groups[3].Value.Trim(); return(handler); } else { return(null); } } }