private async Task <bool> UpdateBucketStateAsync(string bucketKey, BillingUsageBucketState from, BillingUsageBucketState to, CancellationToken cancellationToken) { if (to == from) { return(true); } this.bucketStateLock.EnterWriteLock(); bool success = false; try { var bucket = this.buckets[bucketKey]; if (bucket.State == from) { BillingEventSource.Current.Info(BillingEventSource.EmptyTrackingId, this, nameof(this.UpdateBucketStateAsync), OperationStates.Succeeded, $"Updated bucket '{bucketKey}' from {from.ToString()} to {to.ToString()}"); bucket.State = to; success = true; } else { BillingEventSource.Current.Warning(BillingEventSource.EmptyTrackingId, this, nameof(this.UpdateBucketStateAsync), OperationStates.Failed, $"Failed to update bucket '{bucketKey}' from {from.ToString()} to {to.ToString()}. Current state is {bucket.State.ToString()}"); } } catch (Exception ex) { BillingEventSource.Current.Warning(BillingEventSource.EmptyTrackingId, this, nameof(this.UpdateBucketStateAsync), OperationStates.Failed, $"Failed to update bucket '{bucketKey}' from {from.ToString()} to {to.ToString()}. ex={ex.ToString()}"); } finally { this.bucketStateLock.ExitWriteLock(); } // Save new state to reliable store if (success) { try { var bucketStates = await this.stateManager.GetOrAddAsync <IReliableDictionary <string, BillingUsageBucketState> >(BucketStatusKeyName); using (var tx = this.stateManager.CreateTransaction()) { if (!await bucketStates.TryUpdateAsync(tx, bucketKey, to, from, StateOperationTimeout, cancellationToken)) { BillingEventSource.Current.Warning(BillingEventSource.EmptyTrackingId, this, nameof(this.UpdateBucketStateAsync), OperationStates.Failed, $"Failed to update bucket to reliable '{bucketKey}' from {from.ToString()} to {to.ToString()}"); } await tx.CommitAsync(); } } catch (Exception ex) { BillingEventSource.Current.Warning(BillingEventSource.EmptyTrackingId, this, nameof(this.UpdateBucketStateAsync), OperationStates.Failed, $"Failed to update bucket to reliable '{bucketKey}' from {from.ToString()} to {to.ToString()}. ex={ex.ToString()}"); } } return(success); }
public BillingUsageBucket(IReliableStateManager stateManager, string bucketKey, BillingUsageBucketState state) { this.stateManager = stateManager; this.bucketKey = bucketKey; this.State = state; this.bucket = stateManager.GetOrAddAsync <IReliableDictionary <string, ResourceUsageRecord> >(bucketKey).Result; }