public async Task ReadStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
		{
			var tableResult = await _table.ExecuteAsync(TableOperation.Retrieve<DynamicTableEntity>(grainReference.ToKeyString(), grainType));
			if (tableResult.Result == null)
			{
				return;
			}
			var entity = tableResult.Result as DynamicTableEntity;

			var serializer = new JsonSerializer();
			using (var memoryStream = new MemoryStream())
			{
				foreach (var propertyName in entity.Properties.Keys.Where(p => p.StartsWith("d")).OrderBy(p => p))
				{
					var dataPart = entity.Properties[propertyName];
					await memoryStream.WriteAsync(dataPart.BinaryValue, 0, dataPart.BinaryValue.Length);
				}

				memoryStream.Position = 0;
				using (var bsonReader = new BsonReader(memoryStream))
				{
					var data = serializer.Deserialize<Dictionary<string, object>>(bsonReader);
					grainState.SetAll(data);
				}
			}
		}
        public async Task WriteStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
            try
            {
                var collection = await this.EnsureCollection(grainType);
                var documents = await this.Client.ReadDocumentFeedAsync(collection.DocumentsLink);
                var documentId = grainReference.ToKeyString();

                var document = documents.Where(d => d.Id == documentId).FirstOrDefault();

                if(document != null)
                {
                    document.State = grainState.AsDictionary();
                    await this.Client.ReplaceDocumentAsync(document);
                }
                else
                {
                    await this.Client.CreateDocumentAsync(collection.DocumentsLink,
                        new GrainStateDocument { Id = documentId, State = grainState.AsDictionary() });
                }
            }
            catch (Exception ex)
            {
                Log.Error(0, "Error in WriteStateAsync", ex);
            }
        }
        public async Task ReadStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
            if (!(grainState is IAggregateState))
                throw new NotAggregateStateException(grainState.GetType());

            var stream = this.GetStreamName(grainType, grainReference);

            var sliceStart = 0;
            StreamEventsSlice currentSlice;

            do
            {
                var sliceCount = sliceStart + ReadPageSize;

                currentSlice = await this.Connection.ReadStreamEventsForwardAsync(stream, sliceStart, sliceCount, true);

                if (currentSlice.Status == SliceReadStatus.StreamNotFound)
                    return;

                if (currentSlice.Status == SliceReadStatus.StreamDeleted)
                    throw new StreamDeletedException();

                sliceStart = currentSlice.NextEventNumber;

                foreach (var @event in currentSlice.Events)
                {
                    dynamic deserialisedEvent = DeserializeEvent(@event.Event);
                    StateTransformer.ApplyEvent(deserialisedEvent, grainState as IAggregateState);
                }

            } while (!currentSlice.IsEndOfStream);
        }
        public async Task ReadStateAsync(string grainType, GrainReference grainId, IGrainState grainState)
        {
            try
            {
                var blobName = BlobStorageProvider.GetBlobName(grainType, grainId);
                var blob = container.GetBlockBlobReference(blobName);
                var text = await blob.DownloadTextAsync();
                if (string.IsNullOrWhiteSpace(text))
                {
                    return;
                }

                var data = JsonConvert.DeserializeObject(text, grainState.GetType());
                var dict = ((IGrainState)data).AsDictionary();
                grainState.SetAll(dict);
            }
            catch (StorageException ex)
            {
                ;
            }
            catch (Exception ex)
            {
                Log.Error(0, ex.ToString());
            }
        }
Пример #5
0
 public Task<string> WriteStateAsync(string stateStore, string grainStoreKey, IGrainState grainState)
 {
     if (logger.IsVerbose) logger.Verbose("WriteStateAsync for {0} grain: {1} eTag: {2}", stateStore, grainStoreKey, grainState.ETag);
     GrainStateStore storage = GetStoreForGrain(stateStore);
     storage.UpdateGrainState(grainStoreKey, grainState);
     if (logger.IsVerbose) logger.Verbose("Done WriteStateAsync for {0} grain: {1} eTag: {2}", stateStore, grainStoreKey, grainState.ETag);
     return Task.FromResult(grainState.ETag);
 }
 /// <summary>
 /// Reads persisted state from the backing store and deserializes it into the the target
 /// grain state object.
 /// </summary>
 /// <param name="grainType">A string holding the name of the grain class.</param>
 /// <param name="grainReference">Represents the long-lived identity of the grain.</param>
 /// <param name="grainState">A reference to an object to hold the persisted state of the grain.</param>
 /// <returns>Completion promise for this operation.</returns>
 public async Task ReadStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
 {
     if (DataManager == null) throw new ArgumentException("DataManager property not initialized");
     var entityData = await DataManager.Read(grainState.GetType().Name, grainReference.ToKeyString());
     if (entityData != null)
     {
         ConvertFromStorageFormat(grainState, entityData);
     }
 }
        public Task ClearStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
            if (!(grainState is IAggregateState))
                throw new NotAggregateStateException(grainState.GetType());

            var state = grainState as IAggregateState;
            var stream = this.GetStreamName(grainType, grainReference);

            return this.Connection.DeleteStreamAsync(stream, state.Version);
        }
 public async Task WriteStateAsync(string grainType, GrainReference grainId, IGrainState grainState)
 {
     try
     {
         var blobName = BlobStorageProvider.GetBlobName(grainType, grainId);
         var storedData = JsonConvert.SerializeObject(grainState.AsDictionary());
         var blob = container.GetBlockBlobReference(blobName);
         await blob.UploadTextAsync(storedData);
     }
     catch (Exception ex)
     {
         Log.Error(0, ex.ToString());
     }
 }
        public async Task ReadStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
            var stateName = grainState.GetType().Name;
            var key = grainReference.ToKeyString();
            var id = string.Format(CultureInfo.InvariantCulture, "{0}/{1}", stateName, key);

            using (IAsyncDocumentSession session = this.documentStore.OpenAsyncSession())
            {
                var state = await session.LoadAsync<RavenJObject>(id);
                if (state != null)
                {
                    grainState.SetAll(state.ToDictionary(x => x.Key, x => x.Value.Value<object>()));
                }
            }
        }
        public async Task ReadStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
            try
            {
                var collection = await this.EnsureCollection(grainType);
                var documents = await this.Client.ReadDocumentFeedAsync(collection.DocumentsLink);
                var documentId = grainReference.ToKeyString();
                GrainStateDocument document = documents.Where(d => d.Id == documentId).FirstOrDefault();

                if(document != null)
                    grainState.SetAll(document.State);
            }
            catch (Exception ex)
            {
                Log.Error(0, "Error in ReadStateAsync", ex);
            }            
        }
		public Task WriteStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
		{
			var entity = new DynamicTableEntity(grainReference.ToKeyString(), grainType) { ETag = "*" };

			var serializer = new JsonSerializer();
			using (var memoryStream = new MemoryStream())
			{
				using (var bsonWriter = new BsonWriter(memoryStream))
				{
					serializer.Serialize(bsonWriter, grainState.AsDictionary());

					SplitBinaryData(entity, memoryStream.ToArray());
				}
			}

			return _table.ExecuteAsync(TableOperation.InsertOrReplace(entity));
		}
Пример #12
0
        /// <summary> Write state data function for this storage provider without
        /// checking for ETag before update (if there already exists a prior state). </summary>
        /// <see cref="IExtendedStorageProvider.WriteStateWithoutEtagCheckAsync"/>
        public async Task WriteStateWithoutEtagCheckAsync(string grainType, GrainReference grainId, IGrainState grainState)
        {
            var blobName = GetBlobName(grainType, grainId);

            try
            {
                if (this.Log.IsVerbose3)
                {
                    this.Log.Verbose3((int)AzureProviderErrorCode.AzureBlobProvider_Storage_Writing, "Writing: GrainType={0} Grainid={1} ETag={2} to BlobName={3} in Container={4}", grainType, grainId, grainState.ETag, blobName, container.Name);
                }

                var json = JsonConvert.SerializeObject(grainState.State, jsonSettings);

                var blob = container.GetBlockBlobReference(blobName);
                blob.Properties.ContentType = "application/json";

                var containerNotFound = false;
                try
                {
                    await blob.UploadTextAsync(
                        json,
                        Encoding.UTF8,
                        null,
                        null,
                        null).ConfigureAwait(false);
                }
                catch (StorageException exception)
                {
                    var errorCode = exception.RequestInformation.ExtendedErrorInformation.ErrorCode;
                    containerNotFound = errorCode == BlobErrorCodeStrings.ContainerNotFound;
                }
                if (containerNotFound)
                {
                    // if the container does not exist, create it, and make another attempt
                    if (this.Log.IsVerbose3)
                    {
                        this.Log.Verbose3((int)AzureProviderErrorCode.AzureBlobProvider_ContainerNotFound, "Creating container: GrainType={0} Grainid={1} ETag={2} to BlobName={3} in Container={4}", grainType, grainId, grainState.ETag, blobName, container.Name);
                    }
                    await container.CreateIfNotExistsAsync().ConfigureAwait(false);

                    await blob.UploadTextAsync(
                        json,
                        Encoding.UTF8,
                        null,
                        null,
                        null).ConfigureAwait(false);
                }

                grainState.ETag = blob.Properties.ETag;

                if (this.Log.IsVerbose3)
                {
                    this.Log.Verbose3((int)AzureProviderErrorCode.AzureBlobProvider_Storage_DataRead, "Written: GrainType={0} Grainid={1} ETag={2} to BlobName={3} in Container={4}", grainType, grainId, grainState.ETag, blobName, container.Name);
                }
            }
            catch (Exception ex)
            {
                Log.Error((int)AzureProviderErrorCode.AzureBlobProvider_WriteError,
                          string.Format("Error writing: GrainType={0} Grainid={1} ETag={2} to BlobName={3} in Container={4} Exception={5}", grainType, grainId, grainState.ETag, blobName, container.Name, ex.Message),
                          ex);

                throw;
            }
        }
Пример #13
0
        /// <summary> Clear state data function for this storage provider. </summary>
        /// <remarks>
        /// </remarks>
        /// <see cref="IStorageProvider#ClearStateAsync"/>
        public async Task ClearStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
            var primaryKey = grainReference.ToKeyString();

            try
            {
                if (Log.IsVerbose3)
                {
                    Log.Verbose3((int)SimpleSQLServerProviderErrorCodes.SimpleSQLServerProvider_ClearingData,
                                 $"Clearing: GrainType={grainType} Pk={primaryKey} Grainid={grainReference} ETag={grainState.ETag} from DataSource={this.sqlconnBuilder.DataSource} Catalog={this.sqlconnBuilder.InitialCatalog}");
                }
                var entity = new KeyValueStore()
                {
                    GrainKeyId = primaryKey
                };

                using (var conn = new SqlConnection(this.sqlconnBuilder.ConnectionString))
                    using (var db = new KeyValueDbContext(conn, true))
                    {
                        db.KeyValues.Attach(entity);
                        db.KeyValues.Remove(entity);

                        await db.SaveChangesAsync();

                        grainState.ETag = null;
                        //if(grainState.State is GrainState)
                        //	((GrainState)grainState.State).Etag = null;
                    }
            }
            catch (DbUpdateConcurrencyException conCurrenyEx)
            {
                //someone has deleted has this record already
                Log.Error((int)SimpleSQLServerProviderErrorCodes.SimpleSQLServerProvider_DeleteError,
                          $"DbUpdateConcurrencyException ---- we will ignore this Error clearing: GrainType={grainType} GrainId={grainReference} ETag={grainState.ETag} in to DataSource={this.sqlconnBuilder.DataSource + "." + this.sqlconnBuilder.InitialCatalog}",
                          conCurrenyEx);

                //dont throw --- move on
            }
            catch (Exception ex)
            {
                Log.Error((int)SimpleSQLServerProviderErrorCodes.SimpleSQLServerProvider_DeleteError,
                          $"Error clearing: GrainType={grainType} GrainId={grainReference} ETag={grainState.ETag} in to DataSource={this.sqlconnBuilder.DataSource + "." + this.sqlconnBuilder.InitialCatalog}",
                          ex);

                throw;
            }
        }
Пример #14
0
        public void Deserialize(IGrainState grainState, JObject entityData)
        {
            var jsonReader = new JTokenReader(entityData);

            serializer.Populate(jsonReader, grainState.State);
        }
Пример #15
0
        /// <summary> Read state data function for this storage provider. </summary>
        /// <see cref="IStorageProvider.ReadStateAsync"/>
        public async Task ReadStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
            if (tableDataManager == null)
            {
                throw new ArgumentException("GrainState-Table property not initialized");
            }

            string pk = GetKeyString(grainReference);

            if (Log.IsVerbose3)
            {
                Log.Verbose3((int)AzureProviderErrorCode.AzureTableProvider_ReadingData, "Reading: GrainType={0} Pk={1} Grainid={2} from Table={3}", grainType, pk, grainReference, tableName);
            }
            string           partitionKey = pk;
            string           rowKey       = grainType;
            GrainStateRecord record       = await tableDataManager.Read(partitionKey, rowKey).ConfigureAwait(false);

            if (record != null)
            {
                var entity = record.Entity;
                if (entity != null)
                {
                    var loadedState = ConvertFromStorageFormat(entity);
                    grainState.State = loadedState ?? Activator.CreateInstance(grainState.State.GetType());
                    grainState.ETag  = record.ETag;
                }
            }

            // Else leave grainState in previous default condition
        }
Пример #16
0
        /// <summary> Read state data function for this storage provider. </summary>
        /// <see cref="IStorageProvider.ReadStateAsync"/>
        public async Task ReadStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
            if (storage == null) throw new ArgumentException("GrainState-Table property not initialized");

            string partitionKey = GetKeyString(grainReference);
            if (Log.IsVerbose3) Log.Verbose3(ErrorCode.StorageProviderBase, "Reading: GrainType={0} Pk={1} Grainid={2} from Table={3}", grainType, partitionKey, grainReference, tableName);
            string rowKey = AWSUtils.ValidateDynamoDBRowKey(grainType);

            var record = await storage.ReadSingleEntryAsync(tableName,
                new Dictionary<string, AttributeValue>
                {
                    { GRAIN_REFERENCE_PROPERTY_NAME, new AttributeValue(partitionKey) },
                    { GRAIN_TYPE_PROPERTY_NAME, new AttributeValue(rowKey) }
                },
                (fields) =>
                {
                    return new GrainStateRecord
                    {
                        GrainType = fields[GRAIN_TYPE_PROPERTY_NAME].S,
                        GrainReference = fields[GRAIN_REFERENCE_PROPERTY_NAME].S,
                        ETag = int.Parse(fields[ETAG_PROPERTY_NAME].N),
                        BinaryState = fields.ContainsKey(BINARY_STATE_PROPERTY_NAME) ? fields[BINARY_STATE_PROPERTY_NAME].B.ToArray() : null,
                        StringState = fields.ContainsKey(STRING_STATE_PROPERTY_NAME) ? fields[STRING_STATE_PROPERTY_NAME].S : string.Empty
                    };
                }).ConfigureAwait(false);

            if (record != null)
            {
                var loadedState = ConvertFromStorageFormat(record);
                grainState.State = loadedState ?? Activator.CreateInstance(grainState.State.GetType());
                grainState.ETag = record.ETag.ToString();
            }

            // Else leave grainState in previous default condition
        }
        public async Task ReadStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
            var id = this.GetPrimaryKeyObject(grainReference).ToString();

            grainState.State = await this.GetRepository(grainState).ReadAsync(id);
        }
Пример #18
0
        /// <summary> Write state data function for this storage provider. </summary>
        /// <see cref="IStorageProvider#WriteStateAsync"/>
        public virtual async Task WriteStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
            var    keys         = MakeKeys(grainType, grainReference);
            var    data         = grainState.AsDictionary();
            string receivedEtag = grainState.Etag;

            if (Log.IsVerbose2)
            {
                Log.Verbose2("Write {0} ", StorageProviderUtils.PrintOneWrite(keys, data, receivedEtag));
            }

            if (receivedEtag != null && receivedEtag != etag)
            {
                throw new InconsistentStateException(string.Format("Etag mismatch durign Write: Expected = {0} Received = {1}", etag, receivedEtag));
            }

            string key = HierarchicalKeyStore.MakeStoreKey(keys);
            IMemoryStorageGrain storageGrain = GetStorageGrain(key);
            await storageGrain.WriteStateAsync(STATE_STORE_NAME, key, data);

            etag = NewEtag();
        }
Пример #19
0
        /// <summary> Delete / Clear state data function for this storage provider. </summary>
        /// <see cref="IStorageProvider#ClearStateAsync"/>
        public virtual async Task ClearStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
            var    keys = MakeKeys(grainType, grainReference);
            string eTag = grainState.Etag; // TOD: Should this be 'null' for always Delete?

            if (Log.IsVerbose2)
            {
                Log.Verbose2("Delete Keys={0} Etag={1}", StorageProviderUtils.PrintKeys(keys), eTag);
            }

            if (eTag != null && eTag != etag)
            {
                throw new InconsistentStateException(string.Format("Etag mismatch durign Delete: Expected = {0} Received = {1}", this.etag, eTag));
            }

            string key = HierarchicalKeyStore.MakeStoreKey(keys);
            IMemoryStorageGrain storageGrain = GetStorageGrain(key);
            await storageGrain.DeleteStateAsync(STATE_STORE_NAME, key);

            etag = NewEtag();
        }
 public Task ClearStateAsync(string grainType, GrainReference grainReference, IGrainState grainState) => Task.CompletedTask;
Пример #21
0
        /// <summary> Read state data function for this storage provider. </summary>
        /// <see cref="IStorageProvider#ReadStateAsync"/>
        public virtual async Task ReadStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
            var keys = MakeKeys(grainType, grainReference);

            if (Log.IsVerbose2)
            {
                Log.Verbose2("Read Keys={0}", StorageProviderUtils.PrintKeys(keys));
            }

            string id = HierarchicalKeyStore.MakeStoreKey(keys);
            IMemoryStorageGrain          storageGrain = GetStorageGrain(id);
            IDictionary <string, object> state        = await storageGrain.ReadStateAsync(STATE_STORE_NAME, id);

            grainState.SetAll(state);
        }
Пример #22
0
 /// <summary> Delete / Clear state data function for this storage provider. </summary>
 /// <see cref="IStorageProvider.ClearStateAsync"/>
 public override async Task ClearStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
 {
     await MakeFixedLatencyCall(() => base.ClearStateAsync(grainType, grainReference, grainState));
 }
Пример #23
0
        public AppUISettingsGrain(IGrainState <State> state)
        {
            Guard.NotNull(state, nameof(state));

            this.state = state;
        }
Пример #24
0
 /// <summary> Write state data function for this storage provider. </summary>
 /// <see cref="IGrainStorage.WriteStateAsync"/>
 public async Task WriteStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
 {
     await MakeFixedLatencyCall(() => baseGranStorage.WriteStateAsync(grainType, grainReference, grainState));
 }
        /// <summary> Read state data function for this storage provider. </summary>
        /// <see cref="IStorageProvider#ReadStateAsync"/>
        public async Task ReadStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
            var primaryKey = grainReference.ToKeyString();

            if (Log.IsVerbose3)
            {
                Log.Verbose3((int) SimpleSQLServerProviderErrorCodes.SimpleSQLServerProvider_ReadingData,
                    $"Reading: GrainType={grainType} Pk={primaryKey} Grainid={grainReference} from DataSource={this.sqlconnBuilder.DataSource + "." + this.sqlconnBuilder.InitialCatalog}");
            }

            try
            {
                using (var db = new KeyValueDbContext(this.sqlconnBuilder.ConnectionString))
                {
                    switch (this.useJsonOrBinaryFormat)
                    {
                        case StorageFormatEnum.Binary:
                        case StorageFormatEnum.Both:
                            {
                                var value = await db.KeyValues.Where(s => s.GrainKeyId.Equals(primaryKey)).Select(s => new { s.BinaryContent, s.ETag } ).SingleOrDefaultAsync();
                                if (value != null)
                                {
                                    //data = SerializationManager.DeserializeFromByteArray<Dictionary<string, object>>(value);
                                    grainState.State = SerializationManager.DeserializeFromByteArray<object>(value.BinaryContent);
									grainState.ETag = value.ETag;
									if(grainState.State is GrainState)
										((GrainState)grainState.State).Etag = value.ETag;
								}
							}
							break;
                        case StorageFormatEnum.Json:
                            {
                                var value = await db.KeyValues.Where(s => s.GrainKeyId.Equals(primaryKey)).Select(s => new { s.JsonContext, s.ETag }).SingleOrDefaultAsync();
                                if (value != null && !string.IsNullOrEmpty(value.JsonContext))
                                {
                                    //data = JsonConvert.DeserializeObject<Dictionary<string, object>>(value, jsonSettings);
                                    grainState.State = JsonConvert.DeserializeObject(value.JsonContext, grainState.State.GetType(), jsonSettings);
									grainState.ETag = value.ETag;
									if(grainState.State is GrainState)
										((GrainState)grainState.State).Etag = value.ETag;
								}
							}
							break;
                        default:
                            break;
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Error((int) SimpleSQLServerProviderErrorCodes.SimpleSQLServerProvider_ReadError,
                    $"Error reading: GrainType={grainType} Grainid={grainReference} ETag={grainState.ETag} from DataSource={this.sqlconnBuilder.DataSource + "." + this.sqlconnBuilder.InitialCatalog}",
                    ex);
                throw;
            }

        }
Пример #26
0
        public AppsByUserIndexGrain(IGrainState <GrainState> state)
        {
            Guard.NotNull(state, nameof(state));

            this.state = state;
        }
 public Task ClearStateAsync(string grainType, GrainReference grainReference, IGrainState grainState) => TaskDone.Done;
        public async Task WriteStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
            var id = this.GetPrimaryKeyObject(grainReference).ToString();

            await this.GetRepository(grainState).WriteAsync(id, grainState.State);
        }
Пример #29
0
        private async Task WriteStateInternal(IGrainState grainState, GrainStateRecord record, bool clear = false)
        {
            var fields = new Dictionary<string, AttributeValue>();

            if (record.BinaryState != null && record.BinaryState.Length > 0)
            {
                fields.Add(BINARY_STATE_PROPERTY_NAME, new AttributeValue { B = new MemoryStream(record.BinaryState) });
            }
            else if (!string.IsNullOrWhiteSpace(record.StringState))
            {
                fields.Add(STRING_STATE_PROPERTY_NAME, new AttributeValue(record.StringState));
            }

            int newEtag = 0;
            if (clear)
            {
                fields.Add(GRAIN_REFERENCE_PROPERTY_NAME, new AttributeValue(record.GrainReference));
                fields.Add(GRAIN_TYPE_PROPERTY_NAME, new AttributeValue(record.GrainType));

                int currentEtag = 0;
                int.TryParse(grainState.ETag, out currentEtag);
                newEtag = currentEtag;
                fields.Add(ETAG_PROPERTY_NAME, new AttributeValue { N = newEtag++.ToString() });

                await storage.PutEntryAsync(tableName, fields).ConfigureAwait(false);
            }
            else if (string.IsNullOrWhiteSpace(grainState.ETag))
            {
                fields.Add(GRAIN_REFERENCE_PROPERTY_NAME, new AttributeValue(record.GrainReference));
                fields.Add(GRAIN_TYPE_PROPERTY_NAME, new AttributeValue(record.GrainType));
                fields.Add(ETAG_PROPERTY_NAME, new AttributeValue { N = "0" });

                var expression = $"attribute_not_exists({GRAIN_REFERENCE_PROPERTY_NAME}) AND attribute_not_exists({GRAIN_TYPE_PROPERTY_NAME})";
                await storage.PutEntryAsync(tableName, fields, expression).ConfigureAwait(false);
            }
            else
            {
                var keys = new Dictionary<string, AttributeValue>();
                keys.Add(GRAIN_REFERENCE_PROPERTY_NAME, new AttributeValue(record.GrainReference));
                keys.Add(GRAIN_TYPE_PROPERTY_NAME, new AttributeValue(record.GrainType));

                int currentEtag = 0;
                int.TryParse(grainState.ETag, out currentEtag);
                newEtag = currentEtag;
                newEtag++;
                fields.Add(ETAG_PROPERTY_NAME, new AttributeValue { N = newEtag.ToString() });

                var conditionalValues = new Dictionary<string, AttributeValue> { { CURRENT_ETAG_ALIAS, new AttributeValue { N = currentEtag.ToString() } } };
                var expression = $"{ETAG_PROPERTY_NAME} = {CURRENT_ETAG_ALIAS}";
                await storage.UpsertEntryAsync(tableName, keys, fields, expression, conditionalValues).ConfigureAwait(false);
            }

            grainState.ETag = newEtag.ToString();
        }
Пример #30
0
        /// <summary> Read state data function for this storage provider. </summary>
        /// <see cref="IStorageProvider.ReadStateAsync"/>
        public async Task ReadStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
            if (tableDataManager == null) throw new ArgumentException("GrainState-Table property not initialized");

            string pk = GetKeyString(grainReference);
            if (Log.IsVerbose3) Log.Verbose3((int)AzureProviderErrorCode.AzureTableProvider_ReadingData, "Reading: GrainType={0} Pk={1} Grainid={2} from Table={3}", grainType, pk, grainReference, tableName);
            string partitionKey = pk;
            string rowKey = grainType;
            GrainStateRecord record = await tableDataManager.Read(partitionKey, rowKey);
            if (record != null)
            {
                var entity = record.Entity;
                if (entity != null)
                {
                    ConvertFromStorageFormat(grainState, entity);
                    grainState.Etag = record.ETag;
                }
            }
            // Else leave grainState in previous default condition
        }
Пример #31
0
        /// <summary> Clear / Delete state data function for this storage provider. </summary>
        /// <remarks>
        /// If the <c>DeleteStateOnClear</c> is set to <c>true</c> then the table row
        /// for this grain will be deleted / removed, otherwise the table row will be
        /// cleared by overwriting with default / null values.
        /// </remarks>
        /// <see cref="IStorageProvider.ClearStateAsync"/>
        public async Task ClearStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
            if (storage == null)
            {
                throw new ArgumentException("GrainState-Table property not initialized");
            }

            string partitionKey = GetKeyString(grainReference);

            if (Log.IsVerbose3)
            {
                Log.Verbose3(ErrorCode.StorageProviderBase, "Clearing: GrainType={0} Pk={1} Grainid={2} ETag={3} DeleteStateOnClear={4} from Table={5}", grainType, partitionKey, grainReference, grainState.ETag, isDeleteStateOnClear, tableName);
            }
            string rowKey = AWSUtils.ValidateDynamoDBRowKey(grainType);
            var    record = new GrainStateRecord {
                GrainReference = partitionKey, ETag = string.IsNullOrWhiteSpace(grainState.ETag) ? 0 : int.Parse(grainState.ETag), GrainType = rowKey
            };

            var operation = "Clearing";

            try
            {
                if (isDeleteStateOnClear)
                {
                    operation = "Deleting";
                    var keys = new Dictionary <string, AttributeValue>();
                    keys.Add(GRAIN_REFERENCE_PROPERTY_NAME, new AttributeValue(record.GrainReference));
                    keys.Add(GRAIN_TYPE_PROPERTY_NAME, new AttributeValue(record.GrainType));

                    await storage.DeleteEntryAsync(tableName, keys).ConfigureAwait(false);

                    grainState.ETag = string.Empty;
                }
                else
                {
                    await WriteStateInternal(grainState, record, true);
                }
            }
            catch (Exception exc)
            {
                Log.Error(ErrorCode.StorageProviderBase, string.Format("Error {0}: GrainType={1} Grainid={2} ETag={3} from Table={4} Exception={5}",
                                                                       operation, grainType, grainReference, grainState.ETag, tableName, exc.Message), exc);
                throw;
            }
        }
Пример #32
0
        /// <summary> Clear / Delete state data function for this storage provider. </summary>
        /// <remarks>
        /// If the <c>DeleteStateOnClear</c> is set to <c>true</c> then the table row 
        /// for this grain will be deleted / removed, otherwise the table row will be 
        /// cleared by overwriting with default / null values.
        /// </remarks>
        /// <see cref="IStorageProvider.ClearStateAsync"/>
        public async Task ClearStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
            if (tableDataManager == null) throw new ArgumentException("GrainState-Table property not initialized");

            string pk = GetKeyString(grainReference);
            if (Log.IsVerbose3) Log.Verbose3((int)AzureProviderErrorCode.AzureTableProvider_WritingData, "Clearing: GrainType={0} Pk={1} Grainid={2} ETag={3} DeleteStateOnClear={4} from Table={5}", grainType, pk, grainReference, grainState.Etag, isDeleteStateOnClear, tableName);
            var entity = new GrainStateEntity { PartitionKey = pk, RowKey = grainType };
            var record = new GrainStateRecord { Entity = entity, ETag = grainState.Etag };
            string operation = "Clearing";
            try
            {
                if (isDeleteStateOnClear)
                {
                    operation = "Deleting";
                    await tableDataManager.Delete(record);
                }
                else
                {
                    await tableDataManager.Write(record);
                }
                grainState.Etag = record.ETag; // Update in-memory data to the new ETag
            }
            catch (Exception exc)
            {
                Log.Error((int)AzureProviderErrorCode.AzureTableProvider_DeleteError, string.Format("Error {0}: GrainType={1} Grainid={2} ETag={3} from Table={4} Exception={5}",
                    operation, grainType, grainReference, grainState.Etag, tableName, exc.Message), exc);
                throw;
            }
        }
Пример #33
0
 public JObject Serialize(IGrainState grainState)
 {
     return(JObject.FromObject(grainState.State, serializer));
 }
Пример #34
0
 /// <summary>
 /// Deserialize from Azure storage format
 /// </summary>
 /// <param name="grainState">The grain state data to be deserialized in to</param>
 /// <param name="entity">The Azure table entity the stored data</param>
 internal void ConvertFromStorageFormat(IGrainState grainState, GrainStateEntity entity)
 {
     Dictionary<string, object> dataValues = null;
     try
     {
         if (entity.Data != null)
         {
             // Rehydrate
             dataValues = SerializationManager.DeserializeFromByteArray<Dictionary<string, object>>(entity.Data);
         }
         else if (entity.StringData != null)
         {
             dataValues = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, object>>(entity.StringData, jsonSettings);
         }
         if (dataValues != null)
         {
             grainState.SetAll(dataValues);
         }
         // Else, no data found
     }
     catch (Exception exc)
     {
         var sb = new StringBuilder();
         if (entity.Data != null)
         {
             sb.AppendFormat("Unable to convert from storage format GrainStateEntity.Data={0}", entity.Data);
         }
         else if (entity.StringData != null)
         {
             sb.AppendFormat("Unable to convert from storage format GrainStateEntity.StringData={0}", entity.StringData);
         }
         if (dataValues != null)
         {
             int i = 1;
             foreach (var dvKey in dataValues.Keys)
             {
                 object dvValue = dataValues[dvKey];
                 sb.AppendLine();
                 sb.AppendFormat("Data #{0} Key={1} Value={2} Type={3}", i, dvKey, dvValue, dvValue.GetType());
                 i++;
             }
         }
         Log.Error(0, sb.ToString(), exc);
         throw new AggregateException(sb.ToString(), exc);
     }
 }
Пример #35
0
        public async override Task WriteStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
            logger.Info(0, "WriteStateAsync for {0} {1} ErrorInjection={0}", grainType, grainReference, ErrorInjection);
            try
            {
                ThrowIfMatches(ErrorInjectionPoint.BeforeWrite);
                await base.WriteStateAsync(grainType, grainReference, grainState);

                ThrowIfMatches(ErrorInjectionPoint.AfterWrite);
            }
            catch (Exception exc)
            {
                logger.Warn(0, "Injected error during WriteStateAsync for {0} {1} Exception = {2}", grainType, grainReference, exc);
                throw;
            }
        }
Пример #36
0
        /// <summary> Write state data function for this storage provider. </summary>
        /// <see cref="IStorageProvider.WriteStateAsync"/>
        public async Task WriteStateAsync(string grainType, GrainReference grainId, IGrainState grainState)
        {
            var blobName = GetBlobName(grainType, grainId);
            try
            {
                if (this.Log.IsVerbose3) this.Log.Verbose3((int)AzureProviderErrorCode.AzureBlobProvider_Storage_Writing, "Writing: GrainType={0} Grainid={1} ETag={2} to BlobName={3} in Container={4}", grainType, grainId, grainState.ETag, blobName, container.Name);

                var json = JsonConvert.SerializeObject(grainState.State, settings);

                var blob = container.GetBlockBlobReference(blobName);
                blob.Properties.ContentType = "application/json";

                var containerNotFound = false;
                try
                {
                    await blob.UploadTextAsync(
                            json,
                            Encoding.UTF8,
                            AccessCondition.GenerateIfMatchCondition(grainState.ETag),
                            null,
                            null).ConfigureAwait(false);
                }
                catch (StorageException exception)
                {
                    var errorCode = exception.RequestInformation.ExtendedErrorInformation.ErrorCode;
                    containerNotFound = errorCode == BlobErrorCodeStrings.ContainerNotFound;
                }
                if (containerNotFound)
                {
                    // if the container does not exist, create it, and make another attempt
                    if (this.Log.IsVerbose3) this.Log.Verbose3((int)AzureProviderErrorCode.AzureBlobProvider_ContainerNotFound, "Creating container: GrainType={0} Grainid={1} ETag={2} to BlobName={3} in Container={4}", grainType, grainId, grainState.ETag, blobName, container.Name);
                    await container.CreateIfNotExistsAsync().ConfigureAwait(false);

                    await blob.UploadTextAsync(
                        json,
                        Encoding.UTF8,
                        AccessCondition.GenerateIfMatchCondition(grainState.ETag),
                        null,
                        null).ConfigureAwait(false);
                }

                grainState.ETag = blob.Properties.ETag;

                if (this.Log.IsVerbose3) this.Log.Verbose3((int)AzureProviderErrorCode.AzureBlobProvider_Storage_DataRead, "Written: GrainType={0} Grainid={1} ETag={2} to BlobName={3} in Container={4}", grainType, grainId, grainState.ETag, blobName, container.Name);
            }
            catch (Exception ex)
            {
                Log.Error((int)AzureProviderErrorCode.AzureBlobProvider_WriteError,
                    string.Format("Error writing: GrainType={0} Grainid={1} ETag={2} to BlobName={3} in Container={4} Exception={5}", grainType, grainId, grainState.ETag, blobName, container.Name, ex.Message),
                    ex);
            }
        }
Пример #37
0
        public Task ClearStateAsync(string grainType, Orleans.Runtime.GrainReference grainReference, IGrainState grainState)
        {
            var fileInfo = GetFileInfo(grainType, grainReference);

            fileInfo.Delete();
            return(TaskDone.Done);
        }
        /// <summary> Write state data function for this storage provider. </summary>
        /// <see cref="IStorageProvider#WriteStateAsync"/>
        public async Task WriteStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
			if(grainState.State is GrainState)	//WARN: HACK, such a hack
				grainState.ETag = ((GrainState)grainState.State).Etag;

			var primaryKey = grainReference.ToKeyString();
            if (Log.IsVerbose3)
            {
                Log.Verbose3((int) SimpleSQLServerProviderErrorCodes.SimpleSQLServerProvider_WritingData,
                    $"Writing: GrainType={grainType} PrimaryKey={primaryKey} GrainId={grainReference} ETag={grainState.ETag} to DataSource={this.sqlconnBuilder.DataSource + "." + this.sqlconnBuilder.InitialCatalog}");
            }
            try
            {
                var data = grainState.State;

                byte[] payload = null;
                string jsonpayload = string.Empty;

                if (this.useJsonOrBinaryFormat != StorageFormatEnum.Json)
                {
                    payload = SerializationManager.SerializeToByteArray(data);
                }

                if (this.useJsonOrBinaryFormat == StorageFormatEnum.Json || this.useJsonOrBinaryFormat == StorageFormatEnum.Both)
                {
                    jsonpayload = JsonConvert.SerializeObject(data, jsonSettings);
				}

				var kvb = new KeyValueStore()
                {
                    JsonContext = jsonpayload,
                    BinaryContent = payload,
                    GrainKeyId = primaryKey,
					ETag = Guid.NewGuid().ToString()
				};

                using (var db = new KeyValueDbContext(this.sqlconnBuilder.ConnectionString))
                {
					if(grainState.ETag != null)
					{
						var value = await db.KeyValues.Where(s => s.GrainKeyId.Equals(primaryKey)).Select(s => s.ETag).SingleOrDefaultAsync();
						if(value != null && value != grainState.ETag)
						{
							string error = $"Etag mismatch during WriteStateAsync for grain {primaryKey}: Expected = {value ?? "null"} Received = {grainState.ETag}";
							Log.Error(0, error);
							throw new InconsistentStateException(error);
						}
					}

                    db.Set<KeyValueStore>().AddOrUpdate(kvb);

					grainState.ETag = kvb.ETag;
					if(grainState.State is GrainState)
						((GrainState)grainState.State).Etag = kvb.ETag;

					await db.SaveChangesAsync();
                }

			}
			catch (Exception ex)
            {
                Log.Error((int) SimpleSQLServerProviderErrorCodes.SimpleSQLServerProvider_WriteError,
                    $"Error writing: GrainType={grainType} GrainId={grainReference} ETag={grainState.ETag} to DataSource={this.sqlconnBuilder.DataSource + "." + this.sqlconnBuilder.InitialCatalog}",
                    ex);
                throw;
            }
        }
Пример #39
0
        public Task WriteStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
            return(DoAndLog(nameof(WriteStateAsync), async() =>
            {
                var grainCollection = GetCollection(grainType);
                var grainKey = grainReference.ToKeyString();

                var grainData = serializer.Serialize(grainState);

                var etag = grainState.ETag;

                var newData = grainData.ToBson();
                var newETag = Guid.NewGuid().ToString();

                try
                {
                    UpdateOptions update = new UpdateOptions {
                        IsUpsert = true
                    };
                    await grainCollection.UpdateOneAsync(
                        Filter.And(
                            Filter.Eq(FieldId, grainKey),
                            Filter.Eq(FieldEtag, grainState.ETag)
                            ),
                        Update
                        .Set(FieldEtag, newETag)
                        .Set(FieldDoc, newData),
                        update);
                }
                catch (MongoException ex)
                {
                    if (ex.IsDuplicateKey())
                    {
                        await ThrowForOtherEtag(grainCollection, grainKey, etag, ex);

                        var document = new BsonDocument
                        {
                            [FieldId] = grainKey,
                            [FieldEtag] = grainKey,
                            [FieldDoc] = newData
                        };

                        try
                        {
                            await grainCollection.ReplaceOneAsync(Filter.Eq(FieldId, grainKey), document, Upsert);
                        }
                        catch (MongoException ex2)
                        {
                            if (ex2.IsDuplicateKey())
                            {
                                await ThrowForOtherEtag(grainCollection, grainKey, etag, ex2);
                            }
                            else
                            {
                                throw;
                            }
                        }
                    }
                    else
                    {
                        throw;
                    }
                }

                grainState.ETag = newETag;
            }));
        }
Пример #40
0
        /// <summary> Read state data function for this storage provider. </summary>
        /// <see cref="IStorageProvider.ReadStateAsync"/>
        public async Task ReadStateAsync(string grainType, GrainReference grainId, IGrainState grainState)
        {
            var blobName = GetBlobName(grainType, grainId);

            if (this.Log.IsVerbose3)
            {
                this.Log.Verbose3((int)AzureProviderErrorCode.AzureBlobProvider_Storage_Reading, "Reading: GrainType={0} Grainid={1} ETag={2} from BlobName={3} in Container={4}", grainType, grainId, grainState.ETag, blobName, container.Name);
            }

            try
            {
                var blob = container.GetBlockBlobReference(blobName);

                string json;

                try
                {
                    json = await blob.DownloadTextAsync().ConfigureAwait(false);
                }
                catch (StorageException exception)
                {
                    var errorCode = exception.RequestInformation.ExtendedErrorInformation?.ErrorCode;
                    if (errorCode == BlobErrorCodeStrings.BlobNotFound)
                    {
                        if (this.Log.IsVerbose2)
                        {
                            this.Log.Verbose2((int)AzureProviderErrorCode.AzureBlobProvider_BlobNotFound, "BlobNotFound reading: GrainType={0} Grainid={1} ETag={2} from BlobName={3} in Container={4}", grainType, grainId, grainState.ETag, blobName, container.Name);
                        }
                        return;
                    }
                    if (errorCode == BlobErrorCodeStrings.ContainerNotFound)
                    {
                        if (this.Log.IsVerbose2)
                        {
                            this.Log.Verbose2((int)AzureProviderErrorCode.AzureBlobProvider_ContainerNotFound, "ContainerNotFound reading: GrainType={0} Grainid={1} ETag={2} from BlobName={3} in Container={4}", grainType, grainId, grainState.ETag, blobName, container.Name);
                        }
                        return;
                    }

                    throw;
                }

                if (string.IsNullOrWhiteSpace(json))
                {
                    if (this.Log.IsVerbose2)
                    {
                        this.Log.Verbose2((int)AzureProviderErrorCode.AzureBlobProvider_BlobEmpty, "BlobEmpty reading: GrainType={0} Grainid={1} ETag={2} from BlobName={3} in Container={4}", grainType, grainId, grainState.ETag, blobName, container.Name);
                    }
                    return;
                }

                grainState.State = JsonConvert.DeserializeObject(json, grainState.State.GetType(), jsonSettings);
                grainState.ETag  = blob.Properties.ETag;

                if (this.Log.IsVerbose3)
                {
                    this.Log.Verbose3((int)AzureProviderErrorCode.AzureBlobProvider_Storage_DataRead, "Read: GrainType={0} Grainid={1} ETag={2} from BlobName={3} in Container={4}", grainType, grainId, grainState.ETag, blobName, container.Name);
                }
            }
            catch (Exception ex)
            {
                Log.Error((int)AzureProviderErrorCode.AzureBlobProvider_ReadError,
                          string.Format("Error reading: GrainType={0} Grainid={1} ETag={2} from BlobName={3} in Container={4} Exception={5}", grainType, grainId, grainState.ETag, blobName, container.Name, ex.Message),
                          ex);

                throw;
            }
        }
Пример #41
0
        /// <summary> Write state data function for this storage provider.</summary>
        /// <see cref="IStorageProvider.WriteStateAsync"/>
        public async Task WriteStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
            //It assumed these parameters are always valid. If not, an exception will be thrown, even if not as clear
            //as with explicitly checked parameters.
            var data = grainState.State;
            var grainId = GrainIdAndExtensionAsString(grainReference);
            var baseGrainType = ExtractBaseClass(grainType);
            if(Log.IsVerbose3)
            {
                Log.Verbose3((int)RelationalStorageProviderCodes.RelationalProviderWriting, LogString("Writing grain state", ServiceId, Name, grainState.ETag, baseGrainType, grainId.ToString()));
            }

            string storageVersion = null;
            try
            {

                var writeRecord = await Storage.ReadAsync(CurrentOperationalQueries.WriteToStorage, command =>
                {
                    command.AddParameter("GrainIdHash", HashPicker.PickHasher(ServiceId, Name, baseGrainType, grainReference, grainState).Hash(grainId.GetHashBytes()));
                    command.AddParameter("GrainIdN0", grainId.N0Key);
                    command.AddParameter("GrainIdN1", grainId.N1Key);
                    command.AddParameter("GrainTypeHash", HashPicker.PickHasher(ServiceId, Name, baseGrainType, grainReference, grainState).Hash(Encoding.UTF8.GetBytes(baseGrainType)));
                    command.AddParameter("GrainTypeString", (string)baseGrainType);
                    command.AddParameter("GrainIdExtensionString", grainId.StringKey);
                    command.AddParameter("ServiceId", ServiceId);
                    command.AddParameter("GrainStateVersion", !string.IsNullOrWhiteSpace(grainState.ETag) ? int.Parse(grainState.ETag, CultureInfo.InvariantCulture) : default(int?));

                    SerializationChoice serializer = StorageSerializationPicker.PickSerializer(ServiceId, Name, (string)baseGrainType, grainReference, grainState);
                    command.AddParameter("PayloadBinary", (byte[])(serializer.Serializer.Tag == UseBinaryFormatPropertyName ? serializer.Serializer.Serialize(data) : null));
                    command.AddParameter("PayloadJson", (string)(serializer.Serializer.Tag == UseJsonFormatPropertyName ? serializer.Serializer.Serialize(data) : null));
                    command.AddParameter("PayloadXml", (string)(serializer.Serializer.Tag == UseXmlFormatPropertyName ? serializer.Serializer.Serialize(data) : null));
                }, (selector, resultSetCount, token) =>
                { return Task.FromResult(selector.GetValueOrDefault<int?>("NewGrainStateVersion").ToString()); }, CancellationToken.None).ConfigureAwait(false);
                storageVersion = writeRecord.SingleOrDefault();
            }
            catch(Exception ex)
            {
                Log.Error((int)RelationalStorageProviderCodes.RelationalProviderWriteError, LogString("Error writing grain state", ServiceId, Name, grainState.ETag, baseGrainType, grainId.ToString(), ex.Message), ex);
                throw;
            }

            const string OperationString = "WriteState";
            var inconsistentStateException = CheckVersionInconsistency(OperationString, ServiceId, Name, storageVersion, grainState.ETag, baseGrainType, grainId.ToString());
            if(inconsistentStateException != null)
            {
                throw inconsistentStateException;
            }

            //No errors found, the version of the state held by the grain can be updated.
            grainState.ETag = storageVersion;

            if(Log.IsVerbose3)
            {
                Log.Verbose3((int)RelationalStorageProviderCodes.RelationalProviderWrote, LogString("Wrote grain state", ServiceId, Name, grainState.ETag, baseGrainType, grainId.ToString()));
            }
        }
Пример #42
0
        /// <summary> Clear / Delete state data function for this storage provider. </summary>
        /// <remarks>
        /// If the <c>DeleteStateOnClear</c> is set to <c>true</c> then the table row
        /// for this grain will be deleted / removed, otherwise the table row will be
        /// cleared by overwriting with default / null values.
        /// </remarks>
        /// <see cref="IStorageProvider.ClearStateAsync"/>
        public async Task ClearStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
            if (tableDataManager == null)
            {
                throw new ArgumentException("GrainState-Table property not initialized");
            }

            string pk = GetKeyString(grainReference);

            if (logger.IsEnabled(LogLevel.Trace))
            {
                logger.Trace((int)AzureProviderErrorCode.AzureTableProvider_WritingData, "Clearing: GrainType={0} Pk={1} Grainid={2} ETag={3} DeleteStateOnClear={4} from Table={5}", grainType, pk, grainReference, grainState.ETag, this.options.DeleteStateOnClear, this.options.TableName);
            }
            var entity = new DynamicTableEntity(pk, grainType);
            var record = new GrainStateRecord {
                Entity = entity, ETag = grainState.ETag
            };
            string operation = "Clearing";

            try
            {
                if (this.options.DeleteStateOnClear)
                {
                    operation = "Deleting";
                    await DoOptimisticUpdate(() => tableDataManager.Delete(record), grainType, grainReference, this.options.TableName, grainState.ETag).ConfigureAwait(false);
                }
                else
                {
                    await DoOptimisticUpdate(() => tableDataManager.Write(record), grainType, grainReference, this.options.TableName, grainState.ETag).ConfigureAwait(false);
                }

                grainState.ETag = record.ETag; // Update in-memory data to the new ETag
            }
            catch (Exception exc)
            {
                logger.Error((int)AzureProviderErrorCode.AzureTableProvider_DeleteError, string.Format("Error {0}: GrainType={1} Grainid={2} ETag={3} from Table={4} Exception={5}",
                                                                                                       operation, grainType, grainReference, grainState.ETag, this.options.TableName, exc.Message), exc);
                throw;
            }
        }
Пример #43
0
        /// <summary> Write state data function for this storage provider. </summary>
        /// <see cref="IStorageProvider.WriteStateAsync"/>
        public async Task WriteStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
            if (tableDataManager == null) throw new ArgumentException("GrainState-Table property not initialized");

            string pk = GetKeyString(grainReference);
            if (Log.IsVerbose3)
                Log.Verbose3((int)AzureProviderErrorCode.AzureTableProvider_WritingData, "Writing: GrainType={0} Pk={1} Grainid={2} ETag={3} to Table={4}", grainType, pk, grainReference, grainState.Etag, tableName);

            var entity = new GrainStateEntity { PartitionKey = pk, RowKey = grainType };
            ConvertToStorageFormat(grainState, entity);
            var record = new GrainStateRecord { Entity = entity, ETag = grainState.Etag };
            try
            {
                await tableDataManager.Write(record);
                grainState.Etag = record.ETag;
            }
            catch (Exception exc)
            {
                Log.Error((int)AzureProviderErrorCode.AzureTableProvider_WriteError, string.Format("Error Writing: GrainType={0} Grainid={1} ETag={2} to Table={3} Exception={4}",
                    grainType, grainReference, grainState.Etag, tableName, exc.Message), exc);
                throw;
            }
        }
Пример #44
0
        /// <summary> Write state data function for this storage provider. </summary>
        /// <see cref="IStorageProvider.WriteStateAsync"/>
        public async Task WriteStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
            if (tableDataManager == null)
            {
                throw new ArgumentException("GrainState-Table property not initialized");
            }

            string pk = GetKeyString(grainReference);

            if (logger.IsEnabled(LogLevel.Trace))
            {
                logger.Trace((int)AzureProviderErrorCode.AzureTableProvider_WritingData, "Writing: GrainType={0} Pk={1} Grainid={2} ETag={3} to Table={4}", grainType, pk, grainReference, grainState.ETag, this.options.TableName);
            }

            var entity = new DynamicTableEntity(pk, grainType);

            ConvertToStorageFormat(grainState.State, entity);
            var record = new GrainStateRecord {
                Entity = entity, ETag = grainState.ETag
            };

            try
            {
                await DoOptimisticUpdate(() => tableDataManager.Write(record), grainType, grainReference, this.options.TableName, grainState.ETag).ConfigureAwait(false);

                grainState.ETag = record.ETag;
            }
            catch (Exception exc)
            {
                logger.Error((int)AzureProviderErrorCode.AzureTableProvider_WriteError,
                             $"Error Writing: GrainType={grainType} Grainid={grainReference} ETag={grainState.ETag} to Table={this.options.TableName} Exception={exc.Message}", exc);
                throw;
            }
        }
Пример #45
0
        /// <summary>
        /// Serialize to Azure storage format in either binary or JSON format.
        /// </summary>
        /// <param name="grainState">The grain state data to be serialized</param>
        /// <param name="entity">The Azure table entity the data should be stored in</param>
        /// <remarks>
        /// See:
        /// http://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer.aspx
        /// for more on the JSON serializer.
        /// </remarks>
        internal void ConvertToStorageFormat(IGrainState grainState, GrainStateEntity entity)
        {
            // Dehydrate
            var dataValues = grainState.AsDictionary();
            int dataSize;

            if (useJsonFormat)
            {
                // http://james.newtonking.com/json/help/index.html?topic=html/T_Newtonsoft_Json_JsonConvert.htm
                string data = Newtonsoft.Json.JsonConvert.SerializeObject(dataValues, jsonSettings);

                if (Log.IsVerbose3) Log.Verbose3("Writing JSON data size = {0} for grain id = Partition={1} / Row={2}",
                    data.Length, entity.PartitionKey, entity.RowKey);
                
                dataSize = data.Length;
                entity.StringData = data;
            }
            else
            {
                // Convert to binary format

                byte[] data = SerializationManager.SerializeToByteArray(dataValues);

                if (Log.IsVerbose3) Log.Verbose3("Writing binary data size = {0} for grain id = Partition={1} / Row={2}",
                    data.Length, entity.PartitionKey, entity.RowKey);
                
                dataSize = data.Length;
                entity.Data = data;
            }
            if (dataSize > MAX_DATA_SIZE)
            {
                var msg = string.Format("Data too large to write to Azure table. Size={0} MaxSize={1}", dataSize, MAX_DATA_SIZE);
                Log.Error(0, msg);
                throw new ArgumentOutOfRangeException("GrainState.Size", msg);
            }
        }
        public async Task ReadStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
            if (this._cosmos == null)
            {
                throw new ArgumentException("GrainState collection not initialized.");
            }

            string id           = this.GetKeyString(grainReference);
            string partitionKey = await this.BuildPartitionKey(grainType, grainReference);

            if (this._logger.IsEnabled(LogLevel.Trace))
            {
                this._logger.Trace(
                    "Reading: GrainType={0} Key={1} Grainid={2} from Collection={3} with PartitionKey={4}",
                    grainType, id, grainReference, this._options.Collection, partitionKey);
            }

            try
            {
                var doc = await ExecuteWithRetries(async() => await this._container.ReadItemAsync <GrainStateEntity>(
                                                       id, new PartitionKey(partitionKey))).ConfigureAwait(false);

                if (doc.Resource.State != null)
                {
                    grainState.State = JsonConvert.DeserializeObject(doc.Resource.State.ToString(), grainState.State.GetType(), this._options.JsonSerializerSettings);
                }
                else
                {
                    grainState.State = Activator.CreateInstance(grainState.State.GetType());
                }

                grainState.ETag = doc.Resource.ETag;
            }
            catch (CosmosException dce)
            {
                if (dce.StatusCode == HttpStatusCode.NotFound)
                {
                    // State is new, just activate a default and return
                    grainState.State = Activator.CreateInstance(grainState.State.GetType());
                    return;
                }

                this._logger.LogError(dce, $"Failure reading state for Grain Type {grainType} with Id {id}.");
                throw dce;
            }
            catch (Exception exc)
            {
                this._logger.LogError(exc, $"Failure reading state for Grain Type {grainType} with Id {id}.");
                throw;
            }
        }
Пример #47
0
        /// <summary> Read state data function for this storage provider. </summary>
        /// <see cref="IStorageProvider.ReadStateAsync"/>
        public async Task ReadStateAsync(string grainType, GrainReference grainId, IGrainState grainState)
        {
            var blobName = GetBlobName(grainType, grainId);
            if (this.Log.IsVerbose3) this.Log.Verbose3((int)AzureProviderErrorCode.AzureBlobProvider_Storage_Reading, "Reading: GrainType={0} Grainid={1} ETag={2} from BlobName={3} in Container={4}", grainType, grainId, grainState.ETag, blobName, container.Name);

            try
            {
                var blob = container.GetBlockBlobReference(blobName);

                string json;

                try
                {
                    json = await blob.DownloadTextAsync().ConfigureAwait(false);
                }
                catch (StorageException exception)
                {
                    var errorCode = exception.RequestInformation.ExtendedErrorInformation.ErrorCode;
                    if (errorCode == BlobErrorCodeStrings.BlobNotFound)
                    {
                        if (this.Log.IsVerbose2) this.Log.Verbose2((int)AzureProviderErrorCode.AzureBlobProvider_BlobNotFound, "BlobNotFound reading: GrainType={0} Grainid={1} ETag={2} from BlobName={3} in Container={4}", grainType, grainId, grainState.ETag, blobName, container.Name);
                        return;
                    }
                    if (errorCode == BlobErrorCodeStrings.ContainerNotFound)
                    {
                        if (this.Log.IsVerbose2) this.Log.Verbose2((int)AzureProviderErrorCode.AzureBlobProvider_ContainerNotFound, "ContainerNotFound reading: GrainType={0} Grainid={1} ETag={2} from BlobName={3} in Container={4}", grainType, grainId, grainState.ETag, blobName, container.Name);
                        return;
                    }

                    throw;
                }

                if (string.IsNullOrWhiteSpace(json))
                {
                    if (this.Log.IsVerbose2) this.Log.Verbose2((int)AzureProviderErrorCode.AzureBlobProvider_BlobEmpty, "BlobEmpty reading: GrainType={0} Grainid={1} ETag={2} from BlobName={3} in Container={4}", grainType, grainId, grainState.ETag, blobName, container.Name);
                    return;
                }

                grainState.State = JsonConvert.DeserializeObject(json, grainState.State.GetType(), settings);
                grainState.ETag = blob.Properties.ETag;

                if (this.Log.IsVerbose3) this.Log.Verbose3((int)AzureProviderErrorCode.AzureBlobProvider_Storage_DataRead, "Read: GrainType={0} Grainid={1} ETag={2} from BlobName={3} in Container={4}", grainType, grainId, grainState.ETag, blobName, container.Name);
            }
            catch (Exception ex)
            {
                Log.Error((int)AzureProviderErrorCode.AzureBlobProvider_ReadError,
                    string.Format("Error reading: GrainType={0} Grainid={1} ETag={2} from BlobName={3} in Container={4} Exception={5}", grainType, grainId, grainState.ETag, blobName, container.Name, ex.Message),
                    ex);
            }
        }
        public async Task WriteStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
            if (this._cosmos == null)
            {
                throw new ArgumentException("GrainState collection not initialized.");
            }

            string id = this.GetKeyString(grainReference);

            string partitionKey = await this.BuildPartitionKey(grainType, grainReference);

            if (this._logger.IsEnabled(LogLevel.Trace))
            {
                this._logger.Trace(
                    "Writing: GrainType={0} Key={1} Grainid={2} ETag={3} from Collection={4} with PartitionKey={5}",
                    grainType, id, grainReference, grainState.ETag, this._options.Collection, partitionKey);
            }

            ItemResponse <GrainStateEntity> response = null;

            try
            {
                var entity = new GrainStateEntity
                {
                    ETag         = grainState.ETag,
                    Id           = id,
                    GrainType    = grainType,
                    State        = grainState.State,
                    PartitionKey = partitionKey
                };

                if (string.IsNullOrWhiteSpace(grainState.ETag))
                {
                    response = await ExecuteWithRetries(() => this._container.CreateItemAsync(
                                                            entity,
                                                            new PartitionKey(partitionKey))).ConfigureAwait(false);

                    grainState.ETag = response.Resource.ETag;
                }
                else
                {
                    response = await ExecuteWithRetries(() =>
                                                        this._container.ReplaceItemAsync(
                                                            entity, entity.Id,
                                                            new PartitionKey(partitionKey),
                                                            new ItemRequestOptions {
                        IfMatchEtag = grainState.ETag
                    }))
                               .ConfigureAwait(false);

                    grainState.ETag = response.Resource.ETag;
                }
            }
            catch (CosmosException dce) when(dce.StatusCode == HttpStatusCode.PreconditionFailed)
            {
                throw new CosmosConditionNotSatisfiedException(grainType, grainReference, this._options.Collection, "Unknown", grainState.ETag, dce);
            }
            catch (Exception exc)
            {
                this._logger.LogError(exc, $"Failure writing state for Grain Type {grainType} with Id {id}.");
                throw;
            }
        }
Пример #49
0
        /// <summary> Clear / Delete state data function for this storage provider. </summary>
        /// <see cref="IStorageProvider.ClearStateAsync"/>
        public async Task ClearStateAsync(string grainType, GrainReference grainId, IGrainState grainState)
        {
            var blobName = GetBlobName(grainType, grainId);
            try
            {
                if (this.Log.IsVerbose3) this.Log.Verbose3((int)AzureProviderErrorCode.AzureBlobProvider_ClearingData, "Clearing: GrainType={0} Grainid={1} ETag={2} BlobName={3} in Container={4}", grainType, grainId, grainState.ETag, blobName, container.Name);

                var blob = container.GetBlockBlobReference(blobName);
                await blob.DeleteIfExistsAsync(
                        DeleteSnapshotsOption.None,
                        AccessCondition.GenerateIfMatchCondition(grainState.ETag),
                        null,
                        null).ConfigureAwait(false);
                grainState.ETag = blob.Properties.ETag;

                if (this.Log.IsVerbose3) this.Log.Verbose3((int)AzureProviderErrorCode.AzureBlobProvider_Cleared, "Cleared: GrainType={0} Grainid={1} ETag={2} BlobName={3} in Container={4}", grainType, grainId, grainState.ETag, blobName, container.Name);
            }
            catch (Exception ex)
            {
                Log.Error((int)AzureProviderErrorCode.AzureBlobProvider_ClearError,
                  string.Format("Error clearing: GrainType={0} Grainid={1} ETag={2} BlobName={3} in Container={4} Exception={5}", grainType, grainId, grainState.ETag, blobName, container.Name, ex.Message),
                  ex);
            }
        }
        public async Task ClearStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
            if (this._cosmos == null)
            {
                throw new ArgumentException("GrainState collection not initialized.");
            }

            string id           = this.GetKeyString(grainReference);
            string partitionKey = await this.BuildPartitionKey(grainType, grainReference);

            if (this._logger.IsEnabled(LogLevel.Trace))
            {
                this._logger.Trace(
                    "Clearing: GrainType={0} Key={1} Grainid={2} ETag={3} DeleteStateOnClear={4} from Collection={4} with PartitionKey {5}",
                    grainType, id, grainReference, grainState.ETag, this._options.DeleteStateOnClear, this._options.Collection, partitionKey);
            }

            var pk             = new PartitionKey(partitionKey);
            var requestOptions = new ItemRequestOptions {
                IfMatchEtag = grainState.ETag
            };

            try
            {
                if (this._options.DeleteStateOnClear)
                {
                    if (string.IsNullOrWhiteSpace(grainState.ETag))
                    {
                        return;  //state not written
                    }
                    await ExecuteWithRetries(() => this._container.DeleteItemAsync <GrainStateEntity>(
                                                 id, pk, requestOptions));

                    grainState.ETag = null;
                }
                else
                {
                    var entity = new GrainStateEntity
                    {
                        ETag         = grainState.ETag,
                        Id           = id,
                        GrainType    = grainType,
                        State        = null,
                        PartitionKey = partitionKey
                    };

                    var response = await ExecuteWithRetries(() =>
                                                            string.IsNullOrWhiteSpace(grainState.ETag)?
                                                            this._container.CreateItemAsync(entity, pk) :
                                                            this._container.ReplaceItemAsync(entity, entity.Id, pk, requestOptions))
                                   .ConfigureAwait(false);

                    grainState.ETag = response.Resource.ETag;
                }
            }
            catch (Exception exc)
            {
                this._logger.LogError(exc, $"Failure clearing state for Grain Type {grainType} with Id {id}.");
                throw;
            }
        }
		/// <summary> Clear state data function for this storage provider. </summary>
		/// <remarks>
		/// </remarks>
		/// <see cref="IStorageProvider#ClearStateAsync"/>
		public async Task ClearStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
            var primaryKey = grainReference.ToKeyString();

            try
            {
                if (Log.IsVerbose3)
                {
                    Log.Verbose3((int) SimpleSQLServerProviderErrorCodes.SimpleSQLServerStorageProvider_ClearingData,
                        $"Clearing: GrainType={grainType} Pk={primaryKey} Grainid={grainReference} ETag={grainState.ETag} from DataSource={this.sqlconnBuilder.DataSource} Catalog={this.sqlconnBuilder.InitialCatalog}");
                }
                var entity = new KeyValueStore() { GrainKeyId = primaryKey };
                using (var db = new KeyValueDbContext(this.sqlconnBuilder.ConnectionString))
                {
                    db.KeyValues.Attach(entity);
                    db.KeyValues.Remove(entity);

					grainState.ETag = null;
					if(grainState.State is GrainState)
						((GrainState)grainState.State).Etag = null;

					await db.SaveChangesAsync();
                }
			}
			catch (Exception ex)
            {
                Log.Error((int) SimpleSQLServerProviderErrorCodes.SimpleSQLServerProvider_DeleteError,
                  $"Error clearing: GrainType={grainType} GrainId={grainReference} ETag={grainState.ETag} in to DataSource={this.sqlconnBuilder.DataSource + "." + this.sqlconnBuilder.InitialCatalog}",
                  ex);

                throw;
            }
        }
Пример #52
0
        /// <summary> Read state data function for this storage provider. </summary>
        /// <see cref="IGrainStorage.ReadStateAsync"/>
        public virtual async Task ReadStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
            IList <Tuple <string, string> > keys = MakeKeys(grainType, grainReference).ToList();

            if (logger.IsEnabled(LogLevel.Trace))
            {
                logger.Trace("Read Keys={0}", StorageProviderUtils.PrintKeys(keys));
            }

            string id = HierarchicalKeyStore.MakeStoreKey(keys);
            IMemoryStorageGrain storageGrain = GetStorageGrain(id);
            var state = await storageGrain.ReadStateAsync(STATE_STORE_NAME, id);

            if (state != null)
            {
                grainState.ETag  = state.ETag;
                grainState.State = state.State;
            }
        }
Пример #53
0
 /// <summary> Deleet / Clear state data function for this storage provider. </summary>
 /// <see cref="IStorageProvider#ClearStateAsync"/>
 public Task ClearStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
 {
     int num = FindStorageShard(grainType, grainReference);
     IStorageProvider provider = storageProviders[num];
     return provider.ClearStateAsync(grainType, grainReference, grainState);
 }
Пример #54
0
        /// <summary> Write state data function for this storage provider. </summary>
        /// <see cref="IGrainStorage.WriteStateAsync"/>
        public virtual async Task WriteStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
            IList <Tuple <string, string> > keys = MakeKeys(grainType, grainReference).ToList();
            string key = HierarchicalKeyStore.MakeStoreKey(keys);

            if (logger.IsEnabled(LogLevel.Trace))
            {
                logger.Trace("Write {0} ", StorageProviderUtils.PrintOneWrite(keys, grainState.State, grainState.ETag));
            }
            IMemoryStorageGrain storageGrain = GetStorageGrain(key);

            try
            {
                grainState.ETag = await storageGrain.WriteStateAsync(STATE_STORE_NAME, key, grainState);
            }
            catch (MemoryStorageEtagMismatchException e)
            {
                throw e.AsInconsistentStateException();
            }
        }
Пример #55
0
 public override async Task ClearStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
 {
     await MakeFixedLatencyCall(() => base.ClearStateAsync(grainType, grainReference, grainState));
 }
Пример #56
0
        /// <summary> Read state data function for this storage provider. </summary>
        /// <see cref="IStorageProvider.ReadStateAsync"/>
        public async Task ReadStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
            if (storage == null)
            {
                throw new ArgumentException("GrainState-Table property not initialized");
            }

            string partitionKey = GetKeyString(grainReference);

            if (Log.IsVerbose3)
            {
                Log.Verbose3(ErrorCode.StorageProviderBase, "Reading: GrainType={0} Pk={1} Grainid={2} from Table={3}", grainType, partitionKey, grainReference, tableName);
            }
            string rowKey = AWSUtils.ValidateDynamoDBRowKey(grainType);

            var record = await storage.ReadSingleEntryAsync(tableName,
                                                            new Dictionary <string, AttributeValue>
            {
                { GRAIN_REFERENCE_PROPERTY_NAME, new AttributeValue(partitionKey) },
                { GRAIN_TYPE_PROPERTY_NAME, new AttributeValue(rowKey) }
            },
                                                            (fields) =>
            {
                return(new GrainStateRecord
                {
                    GrainType = fields[GRAIN_TYPE_PROPERTY_NAME].S,
                    GrainReference = fields[GRAIN_REFERENCE_PROPERTY_NAME].S,
                    ETag = int.Parse(fields[ETAG_PROPERTY_NAME].N),
                    BinaryState = fields.ContainsKey(BINARY_STATE_PROPERTY_NAME) ? fields[BINARY_STATE_PROPERTY_NAME].B.ToArray() : null,
                    StringState = fields.ContainsKey(STRING_STATE_PROPERTY_NAME) ? fields[STRING_STATE_PROPERTY_NAME].S : string.Empty
                });
            }).ConfigureAwait(false);

            if (record != null)
            {
                var loadedState = ConvertFromStorageFormat(record);
                grainState.State = loadedState ?? Activator.CreateInstance(grainState.State.GetType());
                grainState.ETag  = record.ETag.ToString();
            }

            // Else leave grainState in previous default condition
        }
Пример #57
0
        /// <summary> Write state data function for this storage provider. </summary>
        /// <see cref="IStorageProvider.WriteStateAsync"/>
        public async Task WriteStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
            if (storage == null) throw new ArgumentException("GrainState-Table property not initialized");

            string partitionKey = GetKeyString(grainReference);
            string rowKey = AWSUtils.ValidateDynamoDBRowKey(grainType);

            var record = new GrainStateRecord { GrainReference = partitionKey, GrainType = rowKey };

            try
            {
                ConvertToStorageFormat(grainState.State, record);
                await WriteStateInternal(grainState, record);
            }
            catch (ConditionalCheckFailedException exc)
            {
                throw new InconsistentStateException("Invalid grain state", exc);
            }
            catch (Exception exc)
            {
                Log.Error(ErrorCode.StorageProviderBase, string.Format("Error Writing: GrainType={0} Grainid={1} ETag={2} to Table={3} Exception={4}",
                    grainType, grainReference, grainState.ETag, tableName, exc.Message), exc);
                throw;
            }
        }
Пример #58
0
        /// <summary> Write state data function for this storage provider. </summary>
        /// <see cref="IStorageProvider.WriteStateAsync"/>
        public async Task WriteStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
            if (storage == null)
            {
                throw new ArgumentException("GrainState-Table property not initialized");
            }

            string partitionKey = GetKeyString(grainReference);
            string rowKey       = AWSUtils.ValidateDynamoDBRowKey(grainType);

            var record = new GrainStateRecord {
                GrainReference = partitionKey, GrainType = rowKey
            };

            try
            {
                ConvertToStorageFormat(grainState.State, record);
                await WriteStateInternal(grainState, record);
            }
            catch (ConditionalCheckFailedException exc)
            {
                throw new InconsistentStateException("Invalid grain state", exc);
            }
            catch (Exception exc)
            {
                Log.Error(ErrorCode.StorageProviderBase, string.Format("Error Writing: GrainType={0} Grainid={1} ETag={2} to Table={3} Exception={4}",
                                                                       grainType, grainReference, grainState.ETag, tableName, exc.Message), exc);
                throw;
            }
        }
Пример #59
0
        /// <summary> Clear / Delete state data function for this storage provider. </summary>
        /// <remarks>
        /// If the <c>DeleteStateOnClear</c> is set to <c>true</c> then the table row
        /// for this grain will be deleted / removed, otherwise the table row will be
        /// cleared by overwriting with default / null values.
        /// </remarks>
        /// <see cref="IStorageProvider.ClearStateAsync"/>
        public async Task ClearStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
            if (storage == null) throw new ArgumentException("GrainState-Table property not initialized");

            string partitionKey = GetKeyString(grainReference);
            if (Log.IsVerbose3) Log.Verbose3(ErrorCode.StorageProviderBase, "Clearing: GrainType={0} Pk={1} Grainid={2} ETag={3} DeleteStateOnClear={4} from Table={5}", grainType, partitionKey, grainReference, grainState.ETag, isDeleteStateOnClear, tableName);
            string rowKey = AWSUtils.ValidateDynamoDBRowKey(grainType);
            var record = new GrainStateRecord { GrainReference = partitionKey, ETag = string.IsNullOrWhiteSpace(grainState.ETag) ? 0 : int.Parse(grainState.ETag), GrainType = rowKey };

            var operation = "Clearing";
            try
            {
                if (isDeleteStateOnClear)
                {
                    operation = "Deleting";
                    var keys = new Dictionary<string, AttributeValue>();
                    keys.Add(GRAIN_REFERENCE_PROPERTY_NAME, new AttributeValue(record.GrainReference));
                    keys.Add(GRAIN_TYPE_PROPERTY_NAME, new AttributeValue(record.GrainType));

                    await storage.DeleteEntryAsync(tableName, keys).ConfigureAwait(false);
                    grainState.ETag = string.Empty;
                }
                else
                {
                    await WriteStateInternal(grainState, record, true);
                }
            }
            catch (Exception exc)
            {
                Log.Error(ErrorCode.StorageProviderBase, string.Format("Error {0}: GrainType={1} Grainid={2} ETag={3} from Table={4} Exception={5}",
                    operation, grainType, grainReference, grainState.ETag, tableName, exc.Message), exc);
                throw;
            }
        }
Пример #60
0
        private async Task WriteStateInternal(IGrainState grainState, GrainStateRecord record, bool clear = false)
        {
            var fields = new Dictionary <string, AttributeValue>();

            if (record.BinaryState != null && record.BinaryState.Length > 0)
            {
                fields.Add(BINARY_STATE_PROPERTY_NAME, new AttributeValue {
                    B = new MemoryStream(record.BinaryState)
                });
            }
            else if (!string.IsNullOrWhiteSpace(record.StringState))
            {
                fields.Add(STRING_STATE_PROPERTY_NAME, new AttributeValue(record.StringState));
            }

            int newEtag = 0;

            if (clear)
            {
                fields.Add(GRAIN_REFERENCE_PROPERTY_NAME, new AttributeValue(record.GrainReference));
                fields.Add(GRAIN_TYPE_PROPERTY_NAME, new AttributeValue(record.GrainType));

                int currentEtag = 0;
                int.TryParse(grainState.ETag, out currentEtag);
                newEtag = currentEtag;
                fields.Add(ETAG_PROPERTY_NAME, new AttributeValue {
                    N = newEtag++.ToString()
                });

                await storage.PutEntryAsync(tableName, fields).ConfigureAwait(false);
            }
            else if (string.IsNullOrWhiteSpace(grainState.ETag))
            {
                fields.Add(GRAIN_REFERENCE_PROPERTY_NAME, new AttributeValue(record.GrainReference));
                fields.Add(GRAIN_TYPE_PROPERTY_NAME, new AttributeValue(record.GrainType));
                fields.Add(ETAG_PROPERTY_NAME, new AttributeValue {
                    N = "0"
                });

                var expression = $"attribute_not_exists({GRAIN_REFERENCE_PROPERTY_NAME}) AND attribute_not_exists({GRAIN_TYPE_PROPERTY_NAME})";
                await storage.PutEntryAsync(tableName, fields, expression).ConfigureAwait(false);
            }
            else
            {
                var keys = new Dictionary <string, AttributeValue>();
                keys.Add(GRAIN_REFERENCE_PROPERTY_NAME, new AttributeValue(record.GrainReference));
                keys.Add(GRAIN_TYPE_PROPERTY_NAME, new AttributeValue(record.GrainType));

                int currentEtag = 0;
                int.TryParse(grainState.ETag, out currentEtag);
                newEtag = currentEtag;
                newEtag++;
                fields.Add(ETAG_PROPERTY_NAME, new AttributeValue {
                    N = newEtag.ToString()
                });

                var conditionalValues = new Dictionary <string, AttributeValue> {
                    { CURRENT_ETAG_ALIAS, new AttributeValue {
                          N = currentEtag.ToString()
                      } }
                };
                var expression = $"{ETAG_PROPERTY_NAME} = {CURRENT_ETAG_ALIAS}";
                await storage.UpsertEntryAsync(tableName, keys, fields, expression, conditionalValues).ConfigureAwait(false);
            }

            grainState.ETag = newEtag.ToString();
        }