/// <summary> Clear state data function for this storage provider. </summary> /// <remarks> /// </remarks> /// <see cref="IStorageProvider#ClearStateAsync"/> public async Task ClearStateAsync(string grainType, GrainReference grainReference, IGrainState grainState) { var primaryKey = grainReference.ToKeyString(); try { if (Log.IsVerbose3) { Log.Verbose3((int)SimpleSQLServerProviderErrorCodes.SimpleSQLServerStorageProvider_ClearingData, $"Clearing: GrainType={grainType} Pk={primaryKey} Grainid={grainReference} ETag={grainState.ETag} from DataSource={this.sqlconnBuilder.DataSource} Catalog={this.sqlconnBuilder.InitialCatalog}"); } var entity = new KeyValueStore() { GrainKeyId = primaryKey }; using (var db = new KeyValueDbContext(this.sqlconnBuilder.ConnectionString)) { db.KeyValues.Attach(entity); db.KeyValues.Remove(entity); await db.SaveChangesAsync(); } } catch (Exception ex) { Log.Error((int)SimpleSQLServerProviderErrorCodes.SimpleSQLServerProvider_DeleteError, $"Error clearing: GrainType={grainType} GrainId={grainReference} ETag={grainState.ETag} in 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) { 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> Clear state data function for this storage provider. </summary> /// <remarks> /// </remarks> /// <see cref="IStorageProvider#ClearStateAsync"/> public async Task ClearStateAsync(string grainType, GrainReference grainReference, IGrainState grainState) { var primaryKey = grainReference.ToKeyString(); try { if (Log.IsVerbose3) { Log.Verbose3((int)SimpleSQLServerProviderErrorCodes.SimpleSQLServerProvider_ClearingData, $"Clearing: GrainType={grainType} Pk={primaryKey} Grainid={grainReference} ETag={grainState.ETag} from DataSource={this.sqlconnBuilder.DataSource} Catalog={this.sqlconnBuilder.InitialCatalog}"); } var entity = new KeyValueStore() { GrainKeyId = primaryKey }; using (var conn = new SqlConnection(this.sqlconnBuilder.ConnectionString)) using (var db = new KeyValueDbContext(conn, true)) { db.KeyValues.Attach(entity); db.KeyValues.Remove(entity); await db.SaveChangesAsync(); grainState.ETag = null; //if(grainState.State is GrainState) // ((GrainState)grainState.State).Etag = null; } } catch (DbUpdateConcurrencyException conCurrenyEx) { //someone has deleted has this record already Log.Error((int)SimpleSQLServerProviderErrorCodes.SimpleSQLServerProvider_DeleteError, $"DbUpdateConcurrencyException ---- we will ignore this Error clearing: GrainType={grainType} GrainId={grainReference} ETag={grainState.ETag} in to DataSource={this.sqlconnBuilder.DataSource + "." + this.sqlconnBuilder.InitialCatalog}", conCurrenyEx); //dont throw --- move on } catch (Exception ex) { Log.Error((int)SimpleSQLServerProviderErrorCodes.SimpleSQLServerProvider_DeleteError, $"Error clearing: GrainType={grainType} GrainId={grainReference} ETag={grainState.ETag} in 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> Clear state data function for this storage provider. </summary> /// <remarks> /// </remarks> /// <see cref="IStorageProvider#ClearStateAsync"/> public async Task ClearStateAsync(string grainType, GrainReference grainReference, GrainState grainState) { var primaryKey = grainReference.ToKeyString(); if (Log.IsVerbose3) { Log.Verbose3((int)SimpleSQLServerProviderErrorCodes.SimpleSQLServerStorageProvider_ClearingData, "Clearing: GrainType={0} Pk={1} Grainid={2} ETag={3} DeleteStateOnClear={4} from DataSource={5}", grainType, primaryKey, grainReference, grainState.Etag, this.sqlconnBuilder.DataSource + "." + this.sqlconnBuilder.InitialCatalog); } var entity = new KeyValueStore() { GrainKeyId = primaryKey }; using (var db = new KeyValueDbContext(this.sqlconnBuilder.ConnectionString)) { db.KeyValues.Attach(entity); db.KeyValues.Remove(entity); await db.SaveChangesAsync(); } }
/// <summary> Clear state data function for this storage provider. </summary> /// <remarks> /// </remarks> /// <see cref="IStorageProvider#ClearStateAsync"/> public async Task ClearStateAsync(string grainType, GrainReference grainReference, IGrainState grainState) { var primaryKey = grainReference.ToKeyString(); try { if (Log.IsVerbose3) { Log.Verbose3((int) SimpleSQLServerProviderErrorCodes.SimpleSQLServerStorageProvider_ClearingData, $"Clearing: GrainType={grainType} Pk={primaryKey} Grainid={grainReference} ETag={grainState.ETag} from DataSource={this.sqlconnBuilder.DataSource} Catalog={this.sqlconnBuilder.InitialCatalog}"); } var entity = new KeyValueStore() { GrainKeyId = primaryKey }; using (var db = new KeyValueDbContext(this.sqlconnBuilder.ConnectionString)) { db.KeyValues.Attach(entity); db.KeyValues.Remove(entity); grainState.ETag = null; if(grainState.State is GrainState) ((GrainState)grainState.State).Etag = null; await db.SaveChangesAsync(); } } catch (Exception ex) { Log.Error((int) SimpleSQLServerProviderErrorCodes.SimpleSQLServerProvider_DeleteError, $"Error clearing: GrainType={grainType} GrainId={grainReference} ETag={grainState.ETag} in 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 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; } }