/// <summary> /// Construct an Epsilon Greedy HostPool /// /// Epsilon Greedy is an algorithm that allows HostPool not only to track failure state, /// but also to learn about "better" options in terms of speed, and to pick from available hosts /// based on how well they perform. This gives a weighted request rate to better /// performing hosts, while still distributing requests to all hosts (proportionate to their performance). /// /// A good overview of Epsilon Greedy is here http://stevehanov.ca/blog/index.php?id=132 /// /// To compute the weighting scores, we perform a weighted average of recent response times, over the course of /// `decayDuration`. decayDuration may be set to null to use the default value of 5 minutes /// We then use the supplied EpsilonValueCalculator to calculate a score from that weighted average response time. /// </summary> /// <param name="retryDelayInitial">The initial retry delay when a host goes down. Default, null, is 30 seconds.</param> /// <param name="retryDelayMax">The maximum retry delay when a host goes down. Default, null, is 15 minutes.</param> /// <param name="decayDuration">The amount of time to cycle through all EpsilonBuckets (0...120). /// This decay duration is divided by EpsilonBuckets (default: 5 min / 120 buckets = 2.5 seconds per bucket). /// IE: The average will be taken every decayDuration/EpsilonBuckets seconds.</param> /// <param name="calc">Given the weighted average among EpsilonBuckets slot measurements, calculate the host's EpsilonValue using EpsilonCalculators.Linear/Logarithmic/Polynomial(exponent)</param> /// <param name="autoStartDecayTimer">Automatically starts the decay timer. If false, you need to call StartDecayTimer manually for epsilon values to be calculated correctly.</param> public EpsilonGreedyHostPool( TimeSpan?retryDelayInitial, TimeSpan?retryDelayMax, TimeSpan?decayDuration, EpsilonValueCalculator calc, bool autoStartDecayTimer = true) : base(retryDelayInitial, retryDelayMax) { this.decayDuration = decayDuration ?? DefaultDecayDuration; this.calc = calc; this.epsilon = InitialEpsilon; this.weights = Enumerable.Range(1, EpsilonBuckets) .Select(i => i / Convert.ToSingle(EpsilonBuckets)) .ToArray(); if (autoStartDecayTimer) { StartDecayTimer(); } }
/// <summary> /// Construct an Epsilon Greedy HostPool /// /// Epsilon Greedy is an algorithm that allows HostPool not only to track failure state, /// but also to learn about "better" options in terms of speed, and to pick from available hosts /// based on how well they perform. This gives a weighted request rate to better /// performing hosts, while still distributing requests to all hosts (proportionate to their performance). /// /// A good overview of Epsilon Greedy is here http://stevehanov.ca/blog/index.php?id=132 /// /// To compute the weighting scores, we perform a weighted average of recent response times, over the course of /// `decayDuration`. decayDuration may be set to null to use the default value of 5 minutes /// We then use the supplied EpsilonValueCalculator to calculate a score from that weighted average response time. /// </summary> /// <param name="decayDuration">The amount of time to cycle though all EpsilonBuckets (0...120). /// This decay duration is divided by EpsilonBuckets (default: 5 min / 120 buckets = 2.5 seconds per bucket). /// IE: The average will be taken every decayDuration/EpsilonBuckets seconds.</param> /// <param name="calc">Given the weighted average among EpsilonBuckets slot measurements, calculate the host's EpsilonValue using EpsilonCalculators.Linear/Logarithmic/Polynomial(exponent)</param> /// <param name="autoStartDecayTimer">Automatically starts the decay timer. If false, you need to call StartDecayTimer manually for epsilon values to be calculated correctly.</param> public EpsilonGreedyHostPool(TimeSpan?decayDuration, EpsilonValueCalculator calc, bool autoStartDecayTimer = true) : this(null, null, decayDuration, calc, autoStartDecayTimer) { }