Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.QuickPulse.Helpers.QuickPulseQuotaTracker.AccrueQuota C# (CSharp) Method

AccrueQuota() private method

private AccrueQuota ( long currentTimeFullSeconds ) : void
currentTimeFullSeconds long
return void
        private void AccrueQuota(long currentTimeFullSeconds)
        {
            var spin = new SpinWait();

            while (true)
            {
                long lastQuotaAccrualFullSecondsLocal = Interlocked.Read(ref this.lastQuotaAccrualFullSeconds);

                long fullSecondsSinceLastQuotaAccrual = currentTimeFullSeconds - lastQuotaAccrualFullSecondsLocal;

                // fullSecondsSinceLastQuotaAccrual <= 0 means we're in a second for which some thread has already updated this.lastQuotaAccrualFullSeconds
                if (fullSecondsSinceLastQuotaAccrual > 0)
                {
                    // we are in a new second (possibly along with a bunch of competing threads, some of which might actually be in different (also new) seconds)
                    // only one thread will succeed in updating this.lastQuotaAccrualFullSeconds
                    long newValue = lastQuotaAccrualFullSecondsLocal + fullSecondsSinceLastQuotaAccrual;

                    long valueBeforeExchange = Interlocked.CompareExchange(
                        ref this.lastQuotaAccrualFullSeconds,
                        newValue,
                        lastQuotaAccrualFullSecondsLocal);

                    if (valueBeforeExchange == lastQuotaAccrualFullSecondsLocal)
                    {
                        // we have updated this.lastQuotaAccrualFullSeconds, now increase the quota value
                        this.IncreaseQuota(fullSecondsSinceLastQuotaAccrual);

                        break;
                    }
                    else if (valueBeforeExchange >= newValue)
                    {
                        // a thread that was in a later (or same) second has beaten us to updating the value
                        // we don't have to do anything since the time that has passed between the previous
                        // update and this thread's current time has already been accounted for by that other thread
                        break;
                    }
                    else
                    {
                        // a thread that was in an earlier second (but still a later one compared to the previous update) has beaten us to updating the value
                        // we have to repeat the attempt to account for the time that has passed since
                    }
                }
                else
                {
                    // we're within a second that has already been accounted for, do nothing
                    break;
                }

                spin.SpinOnce();
            }
        }