/// <summary> Write state data function for this storage provider. </summary> /// <see cref="IStorageProvider#WriteStateAsync"/> public async Task WriteStateAsync(string grainType, GrainReference grainReference, IGrainState grainState) { 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); } //we really need to be writing an Etag to the db as well var kvb = new KeyValueStore() { JsonContext = jsonpayload, BinaryContent = payload, GrainKeyId = primaryKey, }; using (var db = new KeyValueDbContext(this.sqlconnBuilder.ConnectionString)) { db.Set <KeyValueStore>().AddOrUpdate(kvb); 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> Write state data function for this storage provider. </summary> /// <see cref="IStorageProvider#WriteStateAsync"/> public async Task WriteStateAsync(string grainType, GrainReference grainReference, GrainState grainState) { var primaryKey = grainReference.ToKeyString(); if (Log.IsVerbose3) { Log.Verbose3((int)SimpleSQLServerProviderErrorCodes.SimpleSQLServerProvide_WritingData, "Writing: GrainType={0} PrimaryKey={1} Grainid={2} ETag={3} to DataSource={4}", grainType, primaryKey, grainReference, grainState.Etag, this.sqlconnBuilder.DataSource + "." + this.sqlconnBuilder.InitialCatalog); } var data = grainState.AsDictionary(); 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); } //await redisDatabase.StringSetAsync(primaryKey, json); var kvb = new KeyValueStore() { JsonContext = jsonpayload, BinaryContent = payload, GrainKeyId = primaryKey, }; using (var db = new KeyValueDbContext(this.sqlconnBuilder.ConnectionString)) { db.Set <KeyValueStore>().AddOrUpdate(kvb); await db.SaveChangesAsync(); } }
/// <summary> Write state data function for this storage provider. </summary> /// <see cref="IStorageProvider#WriteStateAsync"/> public async Task WriteStateAsync(string grainType, GrainReference grainReference, IGrainState grainState) { if(grainState.State is GrainState) //WARN: HACK, such a hack grainState.ETag = ((GrainState)grainState.State).Etag; var primaryKey = grainReference.ToKeyString(); if (Log.IsVerbose3) { Log.Verbose3((int) SimpleSQLServerProviderErrorCodes.SimpleSQLServerProvider_WritingData, $"Writing: GrainType={grainType} PrimaryKey={primaryKey} GrainId={grainReference} ETag={grainState.ETag} to DataSource={this.sqlconnBuilder.DataSource + "." + this.sqlconnBuilder.InitialCatalog}"); } try { var data = grainState.State; byte[] payload = null; string jsonpayload = string.Empty; if (this.useJsonOrBinaryFormat != StorageFormatEnum.Json) { payload = SerializationManager.SerializeToByteArray(data); } if (this.useJsonOrBinaryFormat == StorageFormatEnum.Json || this.useJsonOrBinaryFormat == StorageFormatEnum.Both) { jsonpayload = JsonConvert.SerializeObject(data, jsonSettings); } var kvb = new KeyValueStore() { JsonContext = jsonpayload, BinaryContent = payload, GrainKeyId = primaryKey, ETag = Guid.NewGuid().ToString() }; using (var db = new KeyValueDbContext(this.sqlconnBuilder.ConnectionString)) { if(grainState.ETag != null) { var value = await db.KeyValues.Where(s => s.GrainKeyId.Equals(primaryKey)).Select(s => s.ETag).SingleOrDefaultAsync(); if(value != null && value != grainState.ETag) { string error = $"Etag mismatch during WriteStateAsync for grain {primaryKey}: Expected = {value ?? "null"} Received = {grainState.ETag}"; Log.Error(0, error); throw new InconsistentStateException(error); } } db.Set<KeyValueStore>().AddOrUpdate(kvb); grainState.ETag = kvb.ETag; if(grainState.State is GrainState) ((GrainState)grainState.State).Etag = kvb.ETag; await db.SaveChangesAsync(); } } catch (Exception ex) { Log.Error((int) SimpleSQLServerProviderErrorCodes.SimpleSQLServerProvider_WriteError, $"Error writing: GrainType={grainType} GrainId={grainReference} ETag={grainState.ETag} to DataSource={this.sqlconnBuilder.DataSource + "." + this.sqlconnBuilder.InitialCatalog}", ex); throw; } }
/// <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; } }