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()); } }
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; }
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); } }
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 }; }
/// <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); }
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); }
/// <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()); } }
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; } }
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)); }
/// <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; }
/// <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; } }
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); }
/// <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())); } }
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)"); }
private string GetKeyString(GrainReference grainReference) { var key = String.Format("{0}_{1}", this.clusterOptions.ServiceId, grainReference.ToKeyString()); return(AzureTableUtils.SanitizeTableProperty(key)); }
public Task <ReminderEntry> ReadRow(GrainReference grainRef, string reminderName) { return(database.ReadReminderRowAsync(serviceId, grainRef, reminderName)); }
public Task ReadStateAsync(string grainType, GrainReference grainReference, IGrainState grainState) { //assetProcessor.Get(); return(Task.CompletedTask); }
public Task ClearStateAsync(string grainType, GrainReference grainReference, IGrainState grainState) { string key = grainReference.GetPrimaryKeyString(); return(Task.CompletedTask); }
private static string ConstructReminderId(string serviceId, GrainReference grainRef, string reminderName) { return($"{serviceId}_{grainRef.ToKeyString()}_{reminderName}"); }
/// <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; } }
private static IEnumerable <Tuple <string, string> > MakeKeys(string grainType, GrainReference grain) { return(new[] { Tuple.Create("GrainType", grainType), Tuple.Create("GrainId", grain.ToKeyString()) }); }
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); }
// 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; }
private static string GetId(GrainReference grainReference) { return(grainReference.ToKeyString()); }
FileInfo GetFileInfo(string grainType, GrainReference grainReference) { var path = Path.Combine(directory, string.Format("{0}-{1}.json", grainType, grainReference.ToKeyString())); return(new FileInfo(path)); }
/// <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; } }
/// <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)); }
public Task WriteStateAsync(string grainType, GrainReference grainReference, IGrainState grainState) { throw new NotImplementedException(); }
public bool InRange(GrainReference grainReference) { return(InRange(grainReference.GetUniformHashCode())); }
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()}"); }
public Task <ReminderTableData> ReadRows(GrainReference grainRef) { return(database.ReadReminderRowsAsync(serviceId, grainRef)); }
/// <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; } }
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); } }
private static string GetBlobName(string grainType, GrainReference grainId) { return(string.Format("{0}-{1}.json", grainType, grainId.ToKeyString())); }
public override async Task ClearStateAsync(string grainType, GrainReference grainReference, IGrainState grainState) { await MakeFixedLatencyCall(() => base.ClearStateAsync(grainType, grainReference, grainState)); }
/// <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; } }
public static string ConstructPartitionKey(Guid serviceId, GrainReference grainRef) { return(ConstructPartitionKey(serviceId, grainRef.GetUniformHashCode())); }
} // 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)); }
/// <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; }
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()); }
private static IList <Tuple <string, string> > MakeGrainStateKeys(string grainType, GrainReference grainReference) { return(new[] { Tuple.Create("GrainType", grainType), Tuple.Create("GrainId", GetId(grainReference)) }.ToList()); }
/// <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 } } }