private void SetWeightedAverageResponseTime(HostEntry h) { var value = 0f; var lastValue = 0f; var prevIndex = (h.EpsilonIndex - 1) % EpsilonBuckets; //capture the current index //start from 2, skipping the current epsilon index for (var i = 2; i <= EpsilonBuckets; i++) { var pos = (prevIndex + i) % EpsilonBuckets; var counts = h.EpsilonCounts[pos]; // Changing the line below to what I think it should be to get the weights right var weight = weights[i - 1]; if (counts > 0) { //the average //var currentValue = h.EpsilonValues[pos] / Convert.ToSingle(counts); var currentValue = h.EpsilonAvg[pos]; value += currentValue * weight; lastValue = currentValue; } else { value += lastValue * weight; } } h.EpsilonWeightAverage = value; }
public virtual void AddHost(string host, Connection conn) { lock ( hostLock ) { if (shuttingDown) { return; } var oldHostList = this.hostList; var nextHostList = new HostEntry[oldHostList.Length + 1]; Array.Copy(oldHostList, nextHostList, oldHostList.Length); //add new host to the end of the array. Initially, start off as a dead //host. var he = new HostEntry(host) { conn = conn, Dead = true, RetryDelayInitial = RetryDelayInitial, RetryDelayMax = RetryDelayMax }; nextHostList[nextHostList.Length - 1] = he; this.hostList = nextHostList; } }
internal void MarkSuccess(HostEntry h, long start, long end) { var duration = TimeSpan.FromTicks(end - start); var index = h.EpsilonIndex % EpsilonBuckets; var counts = h.EpsilonCounts; var values = h.EpsilonValues; Interlocked.Increment(ref counts[index]); Interlocked.Add(ref values[index], Convert.ToInt64(duration.TotalMilliseconds)); }
public override async Task <string> RunResultAsRawJson(ReqlAst term, object globalOpts, CancellationToken cancelToken) { HostEntry host = GetRoundRobin(); try { return(await host.conn.RunResultAsRawJson(term, globalOpts, cancelToken).ConfigureAwait(false)); } catch (Exception e) when(ExceptionIs.NetworkError(e)) { host.MarkFailed(); throw; } }
public override void RunNoReply(ReqlAst term, object globalOpts) { HostEntry host = GetRoundRobin(); try { host.conn.RunNoReply(term, globalOpts); } catch (Exception e) when(ExceptionIs.NetworkError(e)) { host.MarkFailed(); throw; } }
public override void RunNoReply(ReqlAst term, object globalOpts) { HostEntry host = GetEpsilonGreedy(); try { var start = DateTime.Now.Ticks; host.conn.RunNoReply(term, globalOpts); var end = DateTime.Now.Ticks; MarkSuccess(host, start, end); } catch (Exception e) when(ExceptionIs.NetworkError(e)) { host.MarkFailed(); throw; } }
public override async Task <Cursor <T> > RunCursorAsync <T>(ReqlAst term, object globalOpts, CancellationToken cancelToken) { HostEntry host = GetEpsilonGreedy(); try { var start = DateTime.Now.Ticks; var result = await host.conn.RunCursorAsync <T>(term, globalOpts, cancelToken).ConfigureAwait(false); var end = DateTime.Now.Ticks; MarkSuccess(host, start, end); return(result); } catch (Exception e) when(ExceptionIs.NetworkError(e)) { host.MarkFailed(); throw; } }
internal virtual HostEntry GetEpsilonGreedy() { HostEntry hostToUse = null; //this is our exploration phase var rand = Random.NextDouble(); if (rand < this.epsilon) { this.epsilon = this.epsilon * EpsilonDecay; if (this.epsilon < MinEpsilon) { this.epsilon = MinEpsilon; } return(this.GetRoundRobin()); } var hlist = this.hostList; var ceiling = 0.0d; //find best. for (var i = 0; i < hlist.Length; i++) { var h = hlist[i]; if (!h.Dead && h.EpsilonWeightAverage > 0) { ceiling += h.EpsilonPercentage; if (rand <= ceiling) { hostToUse = h; break; } } } if (hostToUse == null || hostToUse.Dead) { return(this.GetRoundRobin()); } return(hostToUse); }
public void failure_should_double_retry() { var he = new HostEntry("a") { RetryDelayMax = TimeSpan.FromSeconds(300), RetryDelayInitial = TimeSpan.FromSeconds(30) }; he.MarkFailed(); he.Dead.Should().BeTrue(); he.RetryCount.Should().Be(0); he.NextRetry.Should().BeCloseTo(DateTime.Now.AddSeconds(30), precision: 3000); he.RetryFailed(); he.RetryCount.Should().Be(1); he.NextRetry.Should().BeCloseTo(DateTime.Now.AddSeconds(30 * 2), precision: 3000); he.RetryFailed(); he.RetryCount.Should().Be(2); he.NextRetry.Should().BeCloseTo(DateTime.Now.AddSeconds(30 * 2 * 2), precision: 3000); //run it past the maximum Enumerable.Range(1, 30 * 12) .ForEach(i => he.RetryFailed()); he.RetryFailed(); he.NextRetry.Should().BeCloseTo(DateTime.Now + he.RetryDelayMax, precision: 1000); }
private void SetEpsilonValue(HostEntry h) { h.EpsilonValue = this.calc.CalcValueFromAvgResponseTime(h.EpsilonWeightAverage); }