public string ToElasticValue(GrainReference gref)
 {
     ///"GrainReference=00000000000000000000000000000000060000006aa96326+abc"
     /// to
     /// "GrainReference^00000000000000000000000000000000060000006aa96326_abc"
     return gref.ToKeyString().Replace("=", "__").Replace("_", "+");
 }
		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 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());
            }
        }
示例#4
0
 public ReminderTableData ReadRows(GrainReference grainRef)
 {
     Dictionary<string, ReminderEntry> reminders;
     reminderTable.TryGetValue(grainRef, out reminders);
     return reminders == null ? new ReminderTableData() :
         new ReminderTableData(reminders.Values.ToList());
 }
        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 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);
            }
        }
 internal static void OnStorageActivate(IStorageProvider storage, string grainType, GrainReference grain, TimeSpan latency)
 {
     StorageActivateTotal.Increment();
     if (latency > TimeSpan.Zero)
     {
         StorageReadLatency.AddSample(latency);
     }
 }
 public static string CreateIdFrom(GrainReference grainRef,string reminderName)
 {
     if (String.IsNullOrEmpty(reminderName))
         throw new ArgumentNullException("reminderName");
     if (grainRef==null)
         throw new ArgumentNullException("grainRef");
     return grainRef.ToKeyString() + "," + reminderName;
 }
示例#9
0
 public async Task<ReminderEntry> ReadRow(GrainReference grainRef, string reminderName)
 {
     using (var conn = new SqlConnection(connectionString))
     {
         conn.Open();
         return await ReadRowInternal(grainRef, reminderName, conn, null);
     }
 }
 /// <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);
     }
 }
示例#11
0
 private static ReminderEntry CreateReminder(GrainReference grainRef, string reminderName)
 {
     return new ReminderEntry
     {
         GrainRef = grainRef,
         Period = TimeSpan.FromMinutes(1),
         StartAt = DateTime.UtcNow.Add(TimeSpan.FromMinutes(1)),
         ReminderName = reminderName
     };
 }
示例#12
0
 /// <summary>
 /// Throws a storage exception if one has been added for the grain reference for reading.
 /// </summary>
 /// <param name="grainReference"></param>
 /// <returns></returns>
 public Task OnRead(GrainReference grainReference)
 {
     Exception exception;
     if (readFaults.TryGetValue(grainReference, out exception))
     {
         readFaults.Remove(grainReference);
         throw exception;
     }
     return TaskDone.Done;
 }
        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);
        }
 /// <summary>
 /// Remove a row from the table
 /// </summary>
 /// <param name="grainRef"></param>
 /// <param name="reminderName"></param>
 /// <param name="eTag"></param>
 /// <returns>true if a row with <paramref name="grainRef"/> and <paramref name="reminderName"/> existed and was removed successfully, false otherwise</returns>
 public Task<bool> RemoveRow(GrainReference grainRef, string reminderName, string eTag)
 {
     if (logger.IsVerbose) logger.Verbose("RemoveRow entry grainRef = {0}, reminderName = {1}, eTag = {2}", grainRef, reminderName, eTag);
     bool result = remTable.RemoveRow(grainRef, reminderName, eTag);
     if (result == false)
     {
         logger.Warn(ErrorCode.RS_Table_Remove, "RemoveRow failed for grainRef = {0}, ReminderName = {1}, eTag = {2}. Table now is: {3}",
             grainRef.ToDetailedString(), reminderName, eTag, remTable.ReadAll());
     }
     return Task.FromResult(result);
 }
示例#15
0
 private IDictionary<string, object> GetLastState(string grainType, GrainReference grainReference)
 {
     lock (StateStore)
     {
         var keys = MakeGrainStateKeys(grainType, grainReference);
         var storedState = StateStore.ReadRow(keys);
         LastId = GetId(grainReference);
         LastState = storedState;
         return storedState;
     }
 }
 internal static async Task<ElasticReminderEntry> Get(ElasticClient elastic, GrainReference grainRef, string reminderName)
 {
     var op = await elastic.GetAsync<ElasticReminderEntry>(CreateIdFrom(grainRef, reminderName));
     if (op.IsValid)
     {
         op.Source.ETag = op.Version;
         return op.Source;
     }
     else
         throw new ElasticsearchStorageException();
 }
 private static async Task<string> UpsertReminder(IReminderTable reminder, GrainReference grainRef, string reminderName, DateTime startAt, TimeSpan period)
 {
     var reminderRow = new ReminderEntry
                       {
                           GrainRef = grainRef,
                           Period = period,
                           StartAt = startAt,
                           ReminderName = reminderName
                       };
     return await reminder.UpsertRow(reminderRow);
 }
示例#18
0
        /// <summary>
        /// Createa a GrainIdentity from a grain reference and type name
        /// </summary>
        /// <param name="grainType"></param>
        /// <param name="grainReference"></param>
        /// <returns></returns>
        public static GrainIdentity FromGrainReference(string grainType, GrainReference grainReference)
        {
            Guard.NotNullOrEmpty(grainType, "grainType");
            Guard.NotNull(grainReference, "grainReference");

            return new GrainIdentity()
            {
                GrainType = grainType,
                ShardKey = (int)grainReference.GetUniformHashCode(),
                GrainKey = grainReference.ToKeyString()
            };
        }
        public async Task WriteStateAsync(string grainType, GrainReference grainReference, GrainState 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())
            {
                await session.StoreAsync(grainState, id);
                await session.SaveChangesAsync();
            }
        }
 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());
     }
 }
示例#21
0
        public virtual void SetValue(string grainType, GrainReference grainReference, string name, object val)
        {
            lock (StateStore)
            {
                Log.Info("Setting stored value {0} for {1} to {2}", name, grainReference, val);
                var keys = MakeGrainStateKeys(grainType, grainReference);
                var storedState = StateStore.ReadRow(keys);

                storedState[name] = val;

                LastId = GetId(grainReference);
                LastState = storedState;
            }
        }
示例#22
0
        public async Task<ReminderTableData> ReadRows(GrainReference grainRef)
        {
            using (var conn = new SqlConnection(connectionString))
            {
                conn.Open();

                var command = new SqlCommand(READ_GRAIN_ROWS);
                command.Parameters.Add(new SqlParameter { ParameterName = "@id", DbType = DbType.String, Value = serviceId });
                command.Parameters.Add(new SqlParameter { ParameterName = "@grainid", DbType = DbType.String, Value = grainRef.ToKeyString() });
                command.Connection = conn;

                return await ProcessResults(command);
            }
        }
        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 ClearStateAsync(string grainType, GrainReference grainReference, GrainState 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())
            {
                session.Advanced.Defer(new DeleteCommandData
                {
                    Key = id
                });
                await session.SaveChangesAsync();
            }
        }
        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));
		}
示例#27
0
        /// <summary>
        /// Return all rows that have their GrainReference's.GetUniformHashCode() in the range (start, end]
        /// </summary>
        /// <param name="grainRef"></param>
        /// <param name="reminderName"></param>
        /// <returns></returns>
        public ReminderEntry ReadRow(GrainReference grainRef, string reminderName)
        {
            ReminderEntry result = null;
            Dictionary<string, ReminderEntry> reminders;
            if (reminderTable.TryGetValue(grainRef, out reminders))
            {
                reminders.TryGetValue(reminderName, out result);
            }

            if (logger.IsVerbose3)
            {
                if (result == null)
                    logger.Verbose3("Reminder not found for grain {0} reminder {1} ", grainRef, reminderName);
                else
                    logger.Verbose3("Read for grain {0} reminder {1} row {2}", grainRef, reminderName, result.ToString());
            }
            return result;
        }
示例#28
0
        /// <summary>
        /// Reads a reminder for a grain reference by reminder name.
        /// Read a row from the remider table
        /// </summary>
        /// <param name="grainRef"> grain ref to locate the row </param>
        /// <param name="reminderName"> remider name to locate the row </param>
        /// <returns> Return the RemiderTableData if the rows were read successfully </returns>
        public async Task<ReminderEntry> ReadRow(GrainReference grainRef, string reminderName)
        {
            var reminderId = ConstructReminderId(serviceId, grainRef, reminderName);

            var keys = new Dictionary<string, AttributeValue>
                {
                    { $"{REMINDER_ID_PROPERTY_NAME}", new AttributeValue(reminderId) },
                    { $"{GRAIN_HASH_PROPERTY_NAME}", new AttributeValue { N = grainRef.GetUniformHashCode().ToString() } }
                };

            try
            {
                return await storage.ReadSingleEntryAsync(TABLE_NAME_DEFAULT_VALUE, keys, Resolve).ConfigureAwait(false);
            }
            catch (Exception exc)
            {
                logger.Warn(ErrorCode.ReminderServiceBase,
                    $"Intermediate error reading reminder entry {Utils.DictionaryToString(keys)} from table {TABLE_NAME_DEFAULT_VALUE}.", exc);
                throw;
            }
        }
示例#29
0
        private void SendRequestMessage(GrainReference target, Message message, TaskCompletionSource<object> context, Action<Message, TaskCompletionSource<object>> callback, string debugContext = null, InvokeMethodOptions options = InvokeMethodOptions.None, string genericArguments = null)
        {
            var targetGrainId = target.GrainId;
            var oneWay = (options & InvokeMethodOptions.OneWay) != 0;
            message.SendingGrain = CurrentActivationAddress.Grain;
            message.SendingActivation = CurrentActivationAddress.Activation;
            message.TargetGrain = targetGrainId;
            if (!String.IsNullOrEmpty(genericArguments))
                message.GenericGrainType = genericArguments;

            if (targetGrainId.IsSystemTarget)
            {
                // If the silo isn't be supplied, it will be filled in by the sender to be the gateway silo
                message.TargetSilo = target.SystemTargetSilo;
                if (target.SystemTargetSilo != null)
                {
                    message.TargetActivation = ActivationId.GetSystemActivation(targetGrainId, target.SystemTargetSilo);
                }
            }
            // Client sending messages to another client (observer). Yes, we support that.
            if (target.IsObserverReference)
            {
                message.TargetObserverId = target.ObserverId;
            }
            
            if (debugContext != null)
            {
                message.DebugContext = debugContext;
            }
            if (message.IsExpirableMessage(config))
            {
                // don't set expiration for system target messages.
                message.Expiration = DateTime.UtcNow + responseTimeout + Constants.MAXIMUM_CLOCK_SKEW;
            }

            if (!oneWay)
            {
                var callbackData = new CallbackData(callback, TryResendMessage, context, message, () => UnRegisterCallback(message.Id), config);
                callbacks.TryAdd(message.Id, callbackData);
                callbackData.StartTimer(responseTimeout);
            }

            if (logger.IsVerbose2) logger.Verbose2("Send {0}", message);
            transport.SendMessage(message);
        }
示例#30
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)
        {
            //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 (logger.IsEnabled(LogLevel.Trace))
            {
                logger.Trace((int)RelationalStorageProviderCodes.RelationalProviderWriting, LogString("Writing grain state", serviceId, this.name, grainState.ETag, baseGrainType, grainId.ToString()));
            }

            string storageVersion = null;

            try
            {
                var grainIdHash   = HashPicker.PickHasher(serviceId, this.name, baseGrainType, grainReference, grainState).Hash(grainId.GetHashBytes());
                var grainTypeHash = HashPicker.PickHasher(serviceId, this.name, baseGrainType, grainReference, grainState).Hash(Encoding.UTF8.GetBytes(baseGrainType));
                var writeRecord   = await Storage.ReadAsync(CurrentOperationalQueries.WriteToStorage, command =>
                {
                    command.AddParameter("GrainIdHash", grainIdHash);
                    command.AddParameter("GrainIdN0", grainId.N0Key);
                    command.AddParameter("GrainIdN1", grainId.N1Key);
                    command.AddParameter("GrainTypeHash", grainTypeHash);
                    command.AddParameter("GrainTypeString", 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, this.name, baseGrainType, grainReference, grainState);
                    command.AddParameter("PayloadBinary", (byte[])(serializer.Serializer.Tag == BinaryFormatSerializerTag ? serializer.Serializer.Serialize(data) : null));
                    command.AddParameter("PayloadJson", (string)(serializer.Serializer.Tag == JsonFormatSerializerTag ? serializer.Serializer.Serialize(data) : null));
                    command.AddParameter("PayloadXml", (string)(serializer.Serializer.Tag == XmlFormatSerializerTag ? serializer.Serializer.Serialize(data) : null));
                }, (selector, resultSetCount, token) =>
                                                            { return(Task.FromResult(selector.GetNullableInt32("NewGrainStateVersion").ToString())); }, CancellationToken.None).ConfigureAwait(false);

                storageVersion = writeRecord.SingleOrDefault();
            }
            catch (Exception ex)
            {
                logger.Error((int)RelationalStorageProviderCodes.RelationalProviderWriteError, LogString("Error writing grain state", serviceId, this.name, grainState.ETag, baseGrainType, grainId.ToString(), ex.Message), ex);
                throw;
            }

            const string OperationString            = "WriteState";
            var          inconsistentStateException = CheckVersionInconsistency(OperationString, serviceId, this.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;
            grainState.RecordExists = true;

            if (logger.IsEnabled(LogLevel.Trace))
            {
                logger.Trace((int)RelationalStorageProviderCodes.RelationalProviderWrote, LogString("Wrote grain state", serviceId, this.name, grainState.ETag, baseGrainType, grainId.ToString()));
            }
        }
示例#31
0
        public void Serialize_ArrayOfArrays()
        {
            var    source1      = new[] { new[] { 1, 3, 5 }, new[] { 10, 20, 30 }, new[] { 17, 13, 11, 7, 5, 3, 2 } };
            object deserialized = OrleansSerializationLoop(environment.Serializer, environment.DeepCopier, source1);

            ValidateArrayOfArrays(source1, deserialized, "int");

            var source2 = new[] { new[] { "hello", "goodbye", "yes", "no", "", "I don't know" }, new[] { "yes" } };

            deserialized = OrleansSerializationLoop(environment.Serializer, environment.DeepCopier, source2);
            ValidateArrayOfArrays(source2, deserialized, "string");

            var source3 = new HashSet <string> [3][];

            source3[0]    = new HashSet <string> [2];
            source3[1]    = new HashSet <string> [3];
            source3[2]    = new HashSet <string> [1];
            source3[0][0] = new HashSet <string>();
            source3[0][1] = new HashSet <string>();
            source3[1][0] = new HashSet <string>();
            source3[1][1] = null;
            source3[1][2] = new HashSet <string>();
            source3[2][0] = new HashSet <string>();
            source3[0][0].Add("this");
            source3[0][0].Add("that");
            source3[1][0].Add("the other");
            source3[1][2].Add("and another");
            source3[2][0].Add("but not yet another");
            deserialized = OrleansSerializationLoop(environment.Serializer, environment.DeepCopier, source3);
            var result = Assert.IsAssignableFrom <HashSet <string>[][]>(deserialized); //Array of arrays of hash sets type is wrong on deserialization

            Assert.Equal(3, result.Length);                                            //Outer array size wrong on array of array of sets
            Assert.Equal(2, result[0][0].Count);                                       //Inner set size wrong on array of array of sets, element 0,0
            Assert.Empty(result[0][1]);                                                //Inner set size wrong on array of array of sets, element 0,1
            Assert.Single(result[1][0]);                                               //Inner set size wrong on array of array of sets, element 1,0
            Assert.Null(result[1][1]);                                                 //Inner set not null on array of array of sets, element 1, 1
            Assert.Single(result[1][2]);                                               //Inner set size wrong on array of array of sets, element 1,2
            Assert.Single(result[2][0]);                                               //Inner set size wrong on array of array of sets, element 2,0

            var source4 = new GrainReference[3][];

            source4[0]    = new GrainReference[2];
            source4[1]    = new GrainReference[3];
            source4[2]    = new GrainReference[1];
            source4[0][0] = (GrainReference)environment.InternalGrainFactory.GetGrain(LegacyGrainId.NewId());
            source4[0][1] = (GrainReference)environment.InternalGrainFactory.GetGrain(LegacyGrainId.NewId());
            source4[1][0] = (GrainReference)environment.InternalGrainFactory.GetGrain(LegacyGrainId.NewId());
            source4[1][1] = (GrainReference)environment.InternalGrainFactory.GetGrain(LegacyGrainId.NewId());
            source4[1][2] = (GrainReference)environment.InternalGrainFactory.GetGrain(LegacyGrainId.NewId());
            source4[2][0] = (GrainReference)environment.InternalGrainFactory.GetGrain(LegacyGrainId.NewId());
            deserialized  = OrleansSerializationLoop(environment.Serializer, environment.DeepCopier, source4);
            ValidateArrayOfArrays(source4, deserialized, "grain reference");

            var source5 = new GrainReference[32][];

            for (int i = 0; i < source5.Length; i++)
            {
                source5[i] = new GrainReference[64];
                for (int j = 0; j < source5[i].Length; j++)
                {
                    source5[i][j] = (GrainReference)environment.InternalGrainFactory.GetGrain(LegacyGrainId.NewId());
                }
            }
            deserialized = OrleansSerializationLoop(environment.Serializer, environment.DeepCopier, source5);
            ValidateArrayOfArrays(source5, deserialized, "grain reference (large)");
        }
示例#32
0
        private string GetKeyString(GrainReference grainReference)
        {
            var key = String.Format("{0}_{1}", this.clusterOptions.ServiceId, grainReference.ToKeyString());

            return(AzureTableUtils.SanitizeTableProperty(key));
        }
示例#33
0
 public Task <ReminderEntry> ReadRow(GrainReference grainRef, string reminderName)
 {
     return(database.ReadReminderRowAsync(serviceId, grainRef, reminderName));
 }
示例#34
0
 public Task ReadStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
 {
     //assetProcessor.Get();
     return(Task.CompletedTask);
 }
示例#35
0
        public Task ClearStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
            string key = grainReference.GetPrimaryKeyString();

            return(Task.CompletedTask);
        }
示例#36
0
 private static string ConstructReminderId(string serviceId, GrainReference grainRef, string reminderName)
 {
     return($"{serviceId}_{grainRef.ToKeyString()}_{reminderName}");
 }
示例#37
0
        /// <summary> Read state data function for this storage provider.</summary>
        /// <see cref="IStorageProvider.ReadStateAsync(string, GrainReference, IGrainState)"/>.
        public async Task ReadStateAsync(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 grainId       = GrainIdAndExtensionAsString(grainReference);
            var baseGrainType = ExtractBaseClass(grainType);

            if (Log.IsVerbose3)
            {
                Log.Verbose3((int)RelationalStorageProviderCodes.RelationalProviderReading, LogString("Reading grain state", ServiceId, Name, grainState.ETag, baseGrainType, grainId.ToString()));
            }

            try
            {
                SerializationChoice choice = StorageSerializationPicker.PickDeserializer(ServiceId, Name, baseGrainType, grainReference, grainState, null);
                if (choice.Deserializer == null)
                {
                    var errorString = LogString("No deserializer found", ServiceId, Name, grainState.ETag, baseGrainType, grainId.ToString());
                    Log.Error((int)RelationalStorageProviderCodes.RelationalProviderNoDeserializer, errorString);
                    throw new InvalidOperationException(errorString);
                }

                var commandBehavior = choice.PreferStreaming ? CommandBehavior.SequentialAccess : CommandBehavior.Default;
                var grainStateType  = grainState.State.GetType();
                var readRecords     = (await Storage.ReadAsync(CurrentOperationalQueries.ReadFromStorage, (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", baseGrainType);
                    command.AddParameter("GrainIdExtensionString", grainId.StringKey);
                    command.AddParameter("ServiceId", ServiceId);
                }), async(selector, resultSetCount, token) =>
                {
                    object storageState = null;
                    int?version;
                    if (choice.PreferStreaming)
                    {
                        //When streaming via ADO.NET, using CommandBehavior.SequentialAccess, the order of
                        //the columns on how they are read needs to be exactly this.
                        const int binaryColumnPositionInSelect = 0;
                        const int xmlColumnPositionInSelect = 1;
                        const int jsonColumnPositionInSelect = 2;
                        var streamSelector = (DbDataReader)selector;
                        if (!(await streamSelector.IsDBNullAsync(binaryColumnPositionInSelect)))
                        {
                            using (var downloadStream = streamSelector.GetStream(binaryColumnPositionInSelect, Storage))
                            {
                                storageState = choice.Deserializer.Deserialize(downloadStream, grainStateType);
                            }
                        }

                        if (!(await streamSelector.IsDBNullAsync(xmlColumnPositionInSelect)))
                        {
                            using (var downloadStream = streamSelector.GetTextReader(xmlColumnPositionInSelect))
                            {
                                storageState = choice.Deserializer.Deserialize(downloadStream, grainStateType);
                            }
                        }

                        if (!(await streamSelector.IsDBNullAsync(jsonColumnPositionInSelect)))
                        {
                            using (var downloadStream = streamSelector.GetTextReader(jsonColumnPositionInSelect))
                            {
                                storageState = choice.Deserializer.Deserialize(downloadStream, grainStateType);
                            }
                        }

                        version = await streamSelector.GetValueAsync <int?>("Version");
                    }
                    else
                    {
                        //All but one of these should be null. All will be read and an appropriate deserializer picked.
                        //NOTE: When streaming will be implemented, it is worthwhile to optimize this so that the defined
                        //serializer will be picked and then streaming tried according to its tag.
                        object payload;
                        payload = selector.GetValueOrDefault <byte[]>("PayloadBinary");
                        if (payload == null)
                        {
                            payload = selector.GetValueOrDefault <string>("PayloadXml");
                        }

                        if (payload == null)
                        {
                            payload = selector.GetValueOrDefault <string>("PayloadJson");
                        }

                        if (payload != null)
                        {
                            storageState = choice.Deserializer.Deserialize(payload, grainStateType);
                        }

                        version = selector.GetValue <int?>("Version");
                    }

                    return(Tuple.Create(storageState, version?.ToString(CultureInfo.InvariantCulture)));
                }, CancellationToken.None, commandBehavior).ConfigureAwait(false)).SingleOrDefault();

                object state = readRecords != null ? readRecords.Item1 : null;
                string etag  = readRecords != null ? readRecords.Item2 : null;
                if (state == null)
                {
                    Log.Info((int)RelationalStorageProviderCodes.RelationalProviderNoStateFound, LogString("Null grain state read (default will be instantiated)", ServiceId, Name, grainState.ETag, baseGrainType, grainId.ToString()));
                    state = Activator.CreateInstance(grainStateType);
                }

                grainState.State = state;
                grainState.ETag  = etag;
                if (Log.IsVerbose3)
                {
                    Log.Verbose3((int)RelationalStorageProviderCodes.RelationalProviderRead, LogString("Read grain state", ServiceId, Name, grainState.ETag, baseGrainType, grainId.ToString()));
                }
            }
            catch (Exception ex)
            {
                Log.Error((int)RelationalStorageProviderCodes.RelationalProviderReadError, LogString("Error reading grain state", ServiceId, Name, grainState.ETag, baseGrainType, grainId.ToString(), ex.Message), ex);
                throw;
            }
        }
示例#38
0
 private static IEnumerable <Tuple <string, string> > MakeKeys(string grainType, GrainReference grain)
 {
     return(new[]
     {
         Tuple.Create("GrainType", grainType),
         Tuple.Create("GrainId", grain.ToKeyString())
     });
 }
示例#39
0
        public void SendRequest(GrainReference target, InvokeMethodRequest request, TaskCompletionSource <object> context, Action <Message, TaskCompletionSource <object> > callback, string debugContext = null, InvokeMethodOptions options = InvokeMethodOptions.None, string genericArguments = null)
        {
            var message = Message.CreateMessage(request, options);

            SendRequestMessage(target, message, context, callback, debugContext, options, genericArguments);
        }
示例#40
0
 // This constructor has to be public for JSonSerialization to work!
 // Implement ISerializable if changing it to non-public
 public PubSubPublisherState(StreamId streamId, IStreamProducerExtension streamProducer)
 {
     Stream            = streamId;
     producerReference = streamProducer as GrainReference;
 }
示例#41
0
 private static string GetId(GrainReference grainReference)
 {
     return(grainReference.ToKeyString());
 }
示例#42
0
        FileInfo GetFileInfo(string grainType, GrainReference grainReference)
        {
            var path = Path.Combine(directory, string.Format("{0}-{1}.json", grainType, grainReference.ToKeyString()));

            return(new FileInfo(path));
        }
示例#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 (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 conn = new SqlConnection(this.sqlconnBuilder.ConnectionString))
                    using (var db = new KeyValueDbContext(conn, true))
                    {
                        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 = $"Error writing Etag mismatch: GrainType={grainType} GrainId={grainReference} ETag={grainState.ETag}  Expected = {value ?? "null"} Received = {grainState.ETag}";
                                Log.Error((int)SimpleSQLServerProviderErrorCodes.SimpleSQLServerProvider_WriteError, 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;
            }
        }
示例#44
0
 /// <summary>
 /// Return a hash value derived from the input grain type and id values.
 /// </summary>
 /// <param name="grainType">Fully qualified class type name for this grain</param>
 /// <param name="grainReference">GrainI reference for this grain</param>
 /// <returns>Stable hash value for this grain</returns>
 protected virtual int HashFunction(string grainType, GrainReference grainReference)
 {
     return(StorageProviderUtils.PositiveHash(grainReference, storageProviders.Length));
 }
示例#45
0
 public Task WriteStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
 {
     throw new NotImplementedException();
 }
示例#46
0
 public bool InRange(GrainReference grainReference)
 {
     return(InRange(grainReference.GetUniformHashCode()));
 }
示例#47
0
 public Task <bool> RemoveRow(GrainReference grainRef, string reminderName, string eTag)
 {
     return(database.DeleteReminderRowAsync(serviceId, grainRef, reminderName, eTag));
 }
 private string GetBlobNameString(string grainType, GrainReference grainReference)
 {
     return($"{grainType}-{grainReference.ToKeyString()}");
 }
示例#49
0
 public Task <ReminderTableData> ReadRows(GrainReference grainRef)
 {
     return(database.ReadReminderRowsAsync(serviceId, grainRef));
 }
示例#50
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, jsonSettings);

                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);

                throw;
            }
        }
示例#51
0
 private static async Task DoOptimisticUpdate(Func <Task> updateOperation, string grainType, GrainReference grainReference, string tableName, string currentETag)
 {
     try
     {
         await updateOperation.Invoke().ConfigureAwait(false);
     }
     catch (StorageException ex) when(ex.IsPreconditionFailed() || ex.IsConflict() || ex.IsNotFound())
     {
         throw new TableStorageUpdateConditionNotSatisfiedException(grainType, grainReference, tableName, "Unknown", currentETag, ex);
     }
 }
示例#52
0
 private static string GetBlobName(string grainType, GrainReference grainId)
 {
     return(string.Format("{0}-{1}.json", grainType, grainId.ToKeyString()));
 }
示例#53
0
 public override async Task ClearStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
 {
     await MakeFixedLatencyCall(() => base.ClearStateAsync(grainType, grainReference, grainState));
 }
示例#54
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;
            }
        }
示例#55
0
 public static string ConstructPartitionKey(Guid serviceId, GrainReference grainRef)
 {
     return(ConstructPartitionKey(serviceId, grainRef.GetUniformHashCode()));
 }
示例#56
0
        }                                                     // Part of PartitionKey


        public static string ConstructRowKey(GrainReference grainRef, string reminderName)
        {
            var key = String.Format("{0}-{1}", grainRef.ToKeyString(), reminderName); //grainRef.ToString(), reminderName);

            return(AzureStorageUtils.SanitizeTableProperty(key));
        }
示例#57
0
        /// <summary>
        /// Remove a row from the table
        /// </summary>
        /// <param name="grainRef"></param>
        /// <param name="reminderName"></param>
        /// /// <param name="eTag"></param>
        /// <returns>true if a row with <paramref name="grainRef"/> and <paramref name="reminderName"/> existed and was removed successfully, false otherwise</returns>
        public bool RemoveRow(GrainReference grainRef, string reminderName, string eTag)
        {
            Dictionary<string, ReminderEntry> data = null;
            ReminderEntry e = null;

            // assuming the calling grain executes one call at a time, so no need to lock
            if (!reminderTable.TryGetValue(grainRef, out data))
            {
                logger.Info("1");
                return false;
            }

            data.TryGetValue(reminderName, out e); // check if eTag matches
            if (e == null || !e.ETag.Equals(eTag))
            {
                logger.Info("2");
                return false;
            }

            if (!data.Remove(reminderName))
            {
                logger.Info("3");
                return false;
            }

            if (data.Count == 0)
            {
                reminderTable.Remove(grainRef);
            }
            logger.Info("4");
            return true;
        }
示例#58
0
        internal async Task <List <Tuple <ReminderTableEntry, string> > > FindReminderEntries(GrainReference grainRef)
        {
            var    partitionKey = ReminderTableEntry.ConstructPartitionKey(ServiceId, grainRef);
            string filter       = TableQuery.CombineFilters(
                TableQuery.GenerateFilterCondition(nameof(ReminderTableEntry.RowKey), QueryComparisons.GreaterThan, grainRef.ToKeyString() + '-'),
                TableOperators.And,
                TableQuery.GenerateFilterCondition(nameof(ReminderTableEntry.RowKey), QueryComparisons.LessThanOrEqual,
                                                   grainRef.ToKeyString() + (char)('-' + 1)));
            string query =
                TableQuery.CombineFilters(
                    TableQuery.GenerateFilterCondition(nameof(ReminderTableEntry.PartitionKey), QueryComparisons.Equal, partitionKey),
                    TableOperators.And,
                    filter);

            var queryResults = await ReadTableEntriesAndEtagsAsync(query);

            return(queryResults.ToList());
        }
示例#59
0
 private static IList <Tuple <string, string> > MakeGrainStateKeys(string grainType, GrainReference grainReference)
 {
     return(new[]
     {
         Tuple.Create("GrainType", grainType),
         Tuple.Create("GrainId", GetId(grainReference))
     }.ToList());
 }
示例#60
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)
        {
            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 conn = new SqlConnection(this.sqlconnBuilder.ConnectionString))
                    using (var db = new KeyValueDbContext(conn, true))
                    {
                        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);

                if (!throwOnDeserializeError)
                {
                    await ClearStateAsync(grainType, grainReference, grainState);
                }
                else
                {
                    throw; //this is the default behavior if config option is missing
                }
            }
        }