Exemplo n.º 1
0
        private async Task <bool> PushBucketAsync(BillingUsageBucket bucket, CancellationToken cancellationToken)
        {
            try
            {
                var records = await bucket.GetRecordsAsync(cancellationToken);

                if (records == null || records.Count <= 0)
                {
                    BillingEventSource.Current.Warning(BillingEventSource.EmptyTrackingId, this, nameof(this.PushBucketAsync), OperationStates.Dropped, $"Bucket '{bucket.BucketKey}' has no records.");
                    return(true);
                }

                var batchId = Guid.NewGuid();
                var pushAny = 0;

                // Push to table
                Func <IEnumerable <ResourceUsageRecord>, Guid, Task> pushBatchFunc = async(batch, id) =>
                {
                    bool succeed = await this.PushUsageBatchAsync(batch, id, cancellationToken);

                    if (succeed)
                    {
                        Interlocked.Exchange(ref pushAny, 1);
                    }
                };

                await this.ParallelPushAsync(records, batchId, pushBatchFunc);

                if (pushAny > 0)
                {
                    // Notify to queue
                    await NotifyPushAsync(batchId, cancellationToken);

                    await bucket.ClearAsync();
                }

                return(pushAny > 0);
            }
            catch (Exception ex)
            {
                BillingEventSource.Current.ErrorException(BillingEventSource.EmptyTrackingId, this, nameof(this.PushBucketAsync), OperationStates.Failed, string.Empty, ex);
                return(false);
            }
        }
Exemplo n.º 2
0
        private Task <BillingUsageBucket> GetNextBucketInStateAsync(string fromBucket, bool exclude, List <BillingUsageBucketState> states, CancellationToken cancellationToken)
        {
            // If fromBucket is null, search from begining
            var skip = !string.IsNullOrEmpty(fromBucket);

            BillingUsageBucket bucket = null;

            this.bucketStateLock.EnterReadLock();
            try
            {
                // Loop to 2 * count of bucket size, to start from fromBucket
                for (var i = 0; i < this.buckets.Count * 2; i++)
                {
                    var current = this.buckets.Values.ElementAt(i % this.buckets.Count);
                    if (skip && current.BucketKey == fromBucket)
                    {
                        skip = false;
                        if (exclude)
                        {
                            continue;
                        }
                    }

                    if (skip)
                    {
                        continue;
                    }

                    if (states.Contains(current.State))
                    {
                        bucket = current;
                        break;
                    }
                }
            }
            finally
            {
                this.bucketStateLock.ExitReadLock();
            }

            return(Task.FromResult(bucket));
        }