/// <summary> Write state data function for this storage provider. </summary>
        /// <see cref="IGrainStorage.WriteStateAsync"/>
        public async Task WriteStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
            if (this.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)
            {
                this.logger.Error(ErrorCode.StorageProviderBase,
                                  string.Format("Error Writing: GrainType={0} Grainid={1} ETag={2} to Table={3} Exception={4}",
                                                grainType, grainReference, grainState.ETag, this.options.TableName, exc.Message), exc);
                throw;
            }
        }
Exemplo n.º 2
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="IGrainStorage.ClearStateAsync{T}"/>
        public async Task ClearStateAsync <T>(string grainType, GrainReference grainReference, IGrainState <T> grainState)
        {
            if (this.storage == null)
            {
                throw new ArgumentException("GrainState-Table property not initialized");
            }

            string partitionKey = GetKeyString(grainReference);

            if (this.logger.IsEnabled(LogLevel.Trace))
            {
                this.logger.LogTrace(
                    (int)ErrorCode.StorageProviderBase,
                    "Clearing: GrainType={GrainType} Pk={PartitionKey} GrainId={GrainId} ETag={ETag} DeleteStateOnClear={DeleteStateOnClear} from Table={TableName}",
                    grainType,
                    partitionKey,
                    grainReference?.GrainId,
                    grainState.ETag,
                    this.options.DeleteStateOnClear,
                    this.options.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 (this.options.DeleteStateOnClear)
                {
                    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 this.storage.DeleteEntryAsync(this.options.TableName, keys).ConfigureAwait(false);

                    grainState.ETag = null;
                }
                else
                {
                    await WriteStateInternal(grainState, record, true);
                }
            }
            catch (Exception exc)
            {
                this.logger.LogError(
                    (int)ErrorCode.StorageProviderBase,
                    exc,
                    "Error {Operation}: GrainType={GrainType} GrainId={GrainId} ETag={ETag} from Table={TableName}",
                    operation,
                    grainType,
                    grainReference,
                    grainState.ETag,
                    this.options.TableName);
                throw;
            }
        }
Exemplo n.º 3
0
        /// <summary> Read state data function for this storage provider. </summary>
        /// <see cref="IGrainStorage.ReadStateAsync{T}"/>
        public async Task ReadStateAsync <T>(string grainType, GrainReference grainReference, IGrainState <T> grainState)
        {
            if (this.storage == null)
            {
                throw new ArgumentException("GrainState-Table property not initialized");
            }

            string partitionKey = GetKeyString(grainReference);

            if (this.logger.IsEnabled(LogLevel.Trace))
            {
                this.logger.LogTrace(
                    (int)ErrorCode.StorageProviderBase,
                    "Reading: GrainType={GrainType} Pk={PartitionKey} GrainId={GrainId} from Table={TableName}",
                    grainType,
                    partitionKey,
                    grainReference?.GrainId,
                    this.options.TableName);
            }

            string rowKey = AWSUtils.ValidateDynamoDBRowKey(grainType);

            var record = await this.storage.ReadSingleEntryAsync(this.options.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 : null
                });
            }).ConfigureAwait(false);

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

            // Else leave grainState in previous default condition
        }
Exemplo n.º 4
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;
            }
        }
Exemplo n.º 5
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
        }
Exemplo n.º 6
0
        /// <summary> Write state data function for this storage provider. </summary>
        /// <see cref="IGrainStorage.WriteStateAsync{T}"/>
        public async Task WriteStateAsync <T>(string grainType, GrainReference grainReference, IGrainState <T> grainState)
        {
            if (this.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($"Inconsistent grain state: {exc}");
            }
            catch (Exception exc)
            {
                this.logger.LogError(
                    (int)ErrorCode.StorageProviderBase,
                    exc,
                    "Error Writing: GrainType={GrainType} Grainid={GrainId} ETag={ETag} to Table={TableName}",
                    grainType,
                    grainReference,
                    grainState.ETag,
                    this.options.TableName);
                throw;
            }
        }