예제 #1
0
 public Task AddItem(KeyValuePosition grain)
 {
     if (this.State.Members.ContainsKey(grain.Key))
     {
         this.State.Members[grain.Key] = grain;
     }
     else
     {
         this.State.Members.Add(grain.Key, grain);
     }
     return(this.WriteStateAsync());
 }
예제 #2
0
        public async Task <string> SetValueAndPosition(string value, Position newPosition, string eTag)
        {
            if (null != eTag && eTag != this.State.Etag)
            {
                throw new ArgumentException("eTag");
            }
            if (this.State.CurrentPosition == newPosition)
            {
                return(this.State.Etag);
            }

            var oldPosition = this.State.CurrentPosition;

            this.State.CurrentPosition = newPosition;
            this.State.Value           = value;
            await this.WriteStateAsync();

            // think about what to do when failure happens here.
            // is there a way to wrap these calls in a transaction?
            var kvp = new KeyValuePosition
            {
                ETag     = this.State.Etag,
                Key      = key,
                Position = this.State.CurrentPosition,
                Value    = this.State.Value
            };

            var promises = new List <Task>();

            foreach (var item in oldPosition.GetDelta(newPosition))
            {
                var grain = GrainFactory.GetGrain <IQuadKeyGrain>(item.QuadKey);
                switch (item.Delta)
                {
                case ExtensionMethods.Delta.Join:
                    promises.Add(grain.AddItem(kvp));
                    break;

                case ExtensionMethods.Delta.Leave:
                    promises.Add(grain.RemoveItem(key));
                    break;
                }
            }
            await Task.WhenAll(promises);

            return(this.State.Etag);
        }