Exemplo n.º 1
0
            public async Task <GrainStateRecord> Read(string partitionKey, string rowKey)
            {
                if (logger.IsVerbose3)
                {
                    logger.Verbose3((int)ProviderErrorCode.AzureTableProvider_Storage_Reading, "Reading: PartitionKey={0} RowKey={1} from Table={2}", partitionKey, rowKey, TableName);
                }
                try
                {
                    Tuple <GrainStateEntity, string> data = await tableManager.ReadSingleTableEntryAsync(partitionKey, rowKey);

                    GrainStateEntity stateEntity = data.Item1;
                    var record = new GrainStateRecord {
                        Entity = stateEntity, ETag = data.Item2
                    };
                    if (logger.IsVerbose3)
                    {
                        logger.Verbose3((int)ProviderErrorCode.AzureTableProvider_Storage_DataRead, "Read: PartitionKey={0} RowKey={1} from Table={2} with ETag={3}", stateEntity.PartitionKey, stateEntity.RowKey, TableName, record.ETag);
                    }
                    return(record);
                }
                catch (Exception exc)
                {
                    if (AzureStorageUtils.TableStorageDataNotFound(exc))
                    {
                        if (logger.IsVerbose2)
                        {
                            logger.Verbose2((int)ProviderErrorCode.AzureTableProvider_DataNotFound, "DataNotFound reading: PartitionKey={0} RowKey={1} from Table={2} Exception={3}", partitionKey, rowKey, TableName, exc);
                        }
                        return(null);  // No data
                    }
                    throw;
                }
            }
Exemplo n.º 2
0
        public async Task WriteStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
            string id = GetKeyString(grainReference);

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

                var spResponse = await ExecuteWithRetries(() => this._dbClient.ExecuteStoredProcedureAsync <string>(
                                                              UriFactory.CreateStoredProcedureUri(this._options.DB, this._options.Collection, WRITE_STATE_SPROC),
                                                              new RequestOptions {
                    PartitionKey = new PartitionKey(grainType)
                },
                                                              entity)).ConfigureAwait(false);

                grainState.ETag = spResponse.Response;
            }
            catch (Exception exc)
            {
                this._logger.LogError(exc, $"Failure writing state for Grain Type {grainType} with Id {id}.");
                throw;
            }
        }
        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));
                }
                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;
            }
        }
Exemplo n.º 4
0
            public async Task Delete(GrainStateRecord record)
            {
                GrainStateEntity entity = record.Entity;

                if (logger.IsVerbose3)
                {
                    logger.Verbose3((int)AzureProviderErrorCode.AzureTableProvider_Storage_Writing, "Deleting: PartitionKey={0} RowKey={1} from Table={2} with ETag={3}", entity.PartitionKey, entity.RowKey, TableName, record.ETag);
                }
                await tableManager.DeleteTableEntryAsync(entity, record.ETag);

                record.ETag = null;
            }
Exemplo n.º 5
0
            public async Task Write(GrainStateRecord record)
            {
                GrainStateEntity entity = record.Entity;

                if (logger.IsVerbose3)
                {
                    logger.Verbose3((int)AzureProviderErrorCode.AzureTableProvider_Storage_Writing, "Writing: PartitionKey={0} RowKey={1} to Table={2} with ETag={3}", entity.PartitionKey, entity.RowKey, TableName, record.ETag);
                }
                string eTag = String.IsNullOrEmpty(record.ETag) ?
                              await tableManager.CreateTableEntryAsync(record.Entity) :
                              await tableManager.UpdateTableEntryAsync(entity, record.ETag);

                record.ETag = eTag;
            }
Exemplo n.º 6
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(GrainState 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);
            }
        }
Exemplo n.º 7
0
        public async Task WriteStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
            if (this._dbClient == null)
            {
                throw new ArgumentException("GrainState collection not initialized.");
            }

            string id = GetKeyString(grainReference);

            string partitionKey = await 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);
            }

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

                var entityString = JsonConvert.SerializeObject(entity, this._options.JsonSerializerSettings);

                var spResponse = await ExecuteWithRetries(() => this._dbClient.ExecuteStoredProcedureAsync <string>(
                                                              UriFactory.CreateStoredProcedureUri(this._options.DB, this._options.Collection, WRITE_STATE_SPROC),
                                                              new RequestOptions {
                    PartitionKey = new PartitionKey(partitionKey)
                },
                                                              entityString)).ConfigureAwait(false);

                grainState.ETag = spResponse.Response;
            }
            catch (Exception exc)
            {
                this._logger.LogError(exc, $"Failure writing state for Grain Type {grainType} with Id {id}.");
                throw;
            }
        }
Exemplo n.º 8
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(GrainState 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);
            }
        }
Exemplo n.º 9
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).ConfigureAwait(false);
                }
                else
                {
                    await tableDataManager.Write(record).ConfigureAwait(false);
                }

                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;
            }
        }
Exemplo n.º 10
0
        /// <summary>
        /// Deserialize from Azure storage format
        /// </summary>
        /// <param name="entity">The Azure table entity the stored data</param>
        internal object ConvertFromStorageFormat(GrainStateEntity entity)
        {
            object dataValue = null;

            try
            {
                if (entity.Data != null)
                {
                    // Rehydrate
                    dataValue = SerializationManager.DeserializeFromByteArray <object>(entity.Data);
                }
                else if (entity.StringData != null)
                {
                    dataValue = Newtonsoft.Json.JsonConvert.DeserializeObject <object>(entity.StringData, jsonSettings);
                }

                // 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 (dataValue != null)
                {
                    sb.AppendFormat("Data Value={0} Type={1}", dataValue, dataValue.GetType());
                }

                Log.Error(0, sb.ToString(), exc);
                throw new AggregateException(sb.ToString(), exc);
            }

            return(dataValue);
        }
Exemplo n.º 11
0
        /// <summary> Write state data function for this storage provider. </summary>
        /// <see cref="IStorageProvider.WriteStateAsync"/>
        public async Task WriteStateAsync(string grainType, GrainReference grainReference, GrainState 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;
            }
        }
Exemplo n.º 12
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);
     }
 }
Exemplo n.º 13
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);
            }
        }
Exemplo n.º 14
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;
            }
        }
Exemplo n.º 15
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;
            }
        }
        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;
            }
        }
Exemplo n.º 17
0
        /// <summary>
        /// Deserialize from Azure storage format
        /// </summary>
        /// <param name="entity">The Azure table entity the stored data</param>
        internal object ConvertFromStorageFormat(GrainStateEntity entity)
        {
            object dataValue = null;
            try
            {
                if (entity.Data != null)
                {
                    // Rehydrate
                    dataValue = SerializationManager.DeserializeFromByteArray<object>(entity.Data);
                }
                else if (entity.StringData != null)
                {
                    dataValue = Newtonsoft.Json.JsonConvert.DeserializeObject<object>(entity.StringData, jsonSettings);
                } 

                // 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 (dataValue != null)
                {
                    sb.AppendFormat("Data Value={0} Type={1}", dataValue, dataValue.GetType());
                }

                Log.Error(0, sb.ToString(), exc);
                throw new AggregateException(sb.ToString(), exc);
            }

            return dataValue;
        }