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;
        }
示例#2
0
        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));
        }
示例#4
0
        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;
            }
        }
示例#5
0
        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);


        }
示例#10
0
 private void SetEpsilonValue(HostEntry h)
 {
     h.EpsilonValue = this.calc.CalcValueFromAvgResponseTime(h.EpsilonWeightAverage);
 }