public Task<bool> InsertRow(MembershipEntry entry, TableVersion tableVersion) { if (logger.IsVerbose) logger.Verbose("InsertRow entry = {0}, table version = {1}", entry.ToFullString(), tableVersion); bool result = table.Insert(entry, tableVersion); if (result == false) logger.Info(ErrorCode.MembershipGrainBasedTable2, "Insert of {0} and table version {1} failed. Table now is {2}", entry.ToFullString(), tableVersion, table.ReadAll()); return Task.FromResult(result); }
public Task<bool> UpdateRow(MembershipEntry entry, string etag, TableVersion tableVersion) { if (logger.IsVerbose) logger.Verbose("UpdateRow entry = {0}, etag = {1}, table version = {2}", entry.ToFullString(), etag, tableVersion); bool result = table.Update(entry, etag, tableVersion); if (result == false) logger.Info(ErrorCode.MembershipGrainBasedTable3, "Update of {0}, eTag {1}, table version {2} failed. Table now is {3}", entry.ToFullString(), etag, tableVersion, table.ReadAll()); return Task.FromResult(result); }
public bool Update(MembershipEntry entry, string etag, TableVersion version) { Tuple<MembershipEntry, string> data; siloTable.TryGetValue(entry.SiloAddress, out data); if (data == null) return false; if (!data.Item2.Equals(etag) || !tableVersion.VersionEtag.Equals(version.VersionEtag)) return false; siloTable[entry.SiloAddress] = new Tuple<MembershipEntry, string>( entry, lastETagCounter++.ToString(CultureInfo.InvariantCulture)); tableVersion = new TableVersion(version.Version, NewETag()); return true; }
public async Task<bool> InsertRow(MembershipEntry entry, TableVersion tableVersion) { try { if (logger.IsVerbose) logger.Verbose("InsertRow entry = {0}, table version = {1}", entry.ToFullString(), tableVersion); var tableEntry = Convert(entry, tableManager.DeploymentId); var versionEntry = tableManager.CreateTableVersionEntry(tableVersion.Version); bool result = await tableManager.InsertSiloEntryConditionally( tableEntry, versionEntry, tableVersion.VersionEtag); if (result == false) logger.Warn(ErrorCode.AzureTable_22, String.Format("Insert failed due to contention on the table. Will retry. Entry {0}, table version = {1}", entry.ToFullString(), tableVersion)); return result; } catch (Exception exc) { logger.Warn(ErrorCode.AzureTable_23, String.Format("Intermediate error inserting entry {0} tableVersion {1} to the table {2}.", entry.ToFullString(), (tableVersion == null ? "null" : tableVersion.ToString()), tableManager.TableName), exc); throw; } }
private async Task <bool> DeclareDead(MembershipEntry entry, string etag, TableVersion tableVersion) { if (this.clusterMembershipOptions.LivenessEnabled) { entry = entry.Copy(); // add the killer (myself) to the suspect list, for easier diagnosis later on. entry.AddSuspector(myAddress, DateTime.UtcNow); if (log.IsEnabled(LogLevel.Debug)) { log.Debug("-Going to DeclareDead silo {0} in the table. About to write entry {1}.", entry.SiloAddress, entry.ToFullString()); } entry.Status = SiloStatus.Dead; bool ok = await membershipTableProvider.UpdateRow(entry, etag, tableVersion.Next()); if (ok) { if (log.IsEnabled(LogLevel.Debug)) { log.Debug("-Successfully updated {0} status to Dead in the Membership table.", entry.SiloAddress); } var table = await membershipTableProvider.ReadAll(); this.ProcessTableUpdate(table, "DeclareDead"); GossipToOthers(entry.SiloAddress, entry.Status).Ignore(); return(true); } log.Info(ErrorCode.MembershipMarkDeadWriteFailed, "-Failed to update {0} status to Dead in the Membership table, due to write conflicts. Will retry.", entry.SiloAddress); return(false); } log.Info(ErrorCode.MembershipCantWriteLivenessDisabled, "-Want to mark silo {0} as DEAD, but will ignore because Liveness is Disabled.", entry.SiloAddress); return(true); }
private MembershipTableData Convert(List <Tuple <SiloInstanceTableEntry, string> > entries) { try { var memEntries = new List <Tuple <MembershipEntry, string> >(); TableVersion tableVersion = null; foreach (var tuple in entries) { var tableEntry = tuple.Item1; if (tableEntry.RowKey.Equals(SiloInstanceTableEntry.TABLE_VERSION_ROW)) { tableVersion = new TableVersion(Int32.Parse(tableEntry.MembershipVersion), tuple.Item2); } else { try { MembershipEntry membershipEntry = Parse(tableEntry); memEntries.Add(new Tuple <MembershipEntry, string>(membershipEntry, tuple.Item2)); } catch (Exception exc) { logger.Error((int)TableStorageErrorCode.AzureTable_61, $"Intermediate error parsing SiloInstanceTableEntry to MembershipTableData: {tableEntry}. Ignoring this entry.", exc); } } } var data = new MembershipTableData(memEntries, tableVersion); return(data); } catch (Exception exc) { logger.Error((int)TableStorageErrorCode.AzureTable_60, $"Intermediate error parsing SiloInstanceTableEntry to MembershipTableData: {Utils.EnumerableToString(entries, tuple => tuple.Item1.ToString())}.", exc); throw; } }
public override object Execute(ParameterList parameters, FunctionContextContainer context) { SitemapScope SitemapScope; Expression filter; if (parameters.TryGetParameter <SitemapScope>("SitemapScope", out SitemapScope) == false) { SitemapScope = SitemapScope.Current; } switch (SitemapScope) { case SitemapScope.Current: Guid currentPageId = PageRenderer.CurrentPageId; filter = Expression.Equal(_foreignKeyPropertyExpression, Expression.Constant(currentPageId)); break; case SitemapScope.All: filter = Expression.Constant(true); break; default: Guid pageId = PageRenderer.CurrentPageId; IEnumerable <Guid> pageIds = new FilterWrapper( pageId, SitemapScope, TableVersion.Get(typeof(IPageStructure)), PageStructureInfo.GetAssociatedPageIds(pageId, SitemapScope)); Expression <Func <Guid, bool> > containsExpression = f => pageIds.Contains(f); filter = Expression.Invoke(containsExpression, _foreignKeyPropertyExpression); break; } return(Expression.Lambda <Func <T, bool> >(filter, new ParameterExpression[] { _parameterExpression })); }
public async Task <bool> UpdateRow(MembershipEntry entry, string etag, TableVersion tableVersion) { try { var siloInstance = entry.AsSiloInstance(_clusterId); var clusterVersion = tableVersion.AsClusterVersion(_clusterId); var batch = _mapper.CreateBatch().WithOptions(x => x.SetConsistencyLevel(DefaultConsistencyLevel)); batch.Update(siloInstance); batch.Update(clusterVersion); await _mapper.ExecuteAsync(batch); return(true); } catch (DriverException) { _logger.LogWarning( "Cassandra driver error occured while updating row for silo {silo}, cluster version = {clusterVersion}.", entry.ToString(), tableVersion.Version); throw; } }
public async Task <bool> InsertRow(MembershipEntry entry, TableVersion tableVersion) { try { if (this.logger.IsEnabled(LogLevel.Debug)) { this.logger.Debug("InsertRow entry = {0}", entry.ToFullString()); } var tableEntry = Convert(entry); bool result; try { var expression = $"attribute_not_exists({SiloInstanceRecord.DEPLOYMENT_ID_PROPERTY_NAME}) AND attribute_not_exists({SiloInstanceRecord.SILO_IDENTITY_PROPERTY_NAME})"; await this.storage.PutEntryAsync(this.options.TableName, tableEntry.GetFields(true), expression); result = true; } catch (ConditionalCheckFailedException) { result = false; this.logger.Warn(ErrorCode.MembershipBase, $"Insert failed due to contention on the table. Will retry. Entry {entry.ToFullString()}"); } return(result); } catch (Exception exc) { this.logger.Warn(ErrorCode.MembershipBase, $"Intermediate error inserting entry {entry.ToFullString()} to the table {this.options.TableName}.", exc); throw; } }
public async Task <Boolean> InsertRow(MembershipEntry entry, TableVersion tableVersion) { try { //Use "0" as the eTag then Consul KV CAS will treat the operation as an insert and return false if the KV already exiats. var consulSiloRegistration = ConsulSiloRegistrationAssembler.FromMembershipEntry(_deploymentId, entry, "0"); var insertKV = ConsulSiloRegistrationAssembler.ToKVPair(consulSiloRegistration); var tryUpdate = await _consulClient.KV.CAS(insertKV); if (!tryUpdate.Response) { _logger.Debug("ConsulMembershipProvider failed to insert the row because a registration already exists for silo {0}.", entry.SiloAddress); return(false); } return(true); } catch (Exception ex) { _logger.Info("ConsulMembershipProvider failed to insert registration for silo {0}; {1}.", entry.SiloAddress, ex); throw; } }
public async Task <bool> InsertRow(MembershipEntry entry, TableVersion tableVersion) { try { var siloEntity = ConvertToEntity(entry, this._clusterOptions.ClusterId); var versionEntity = this.BuildVersionEntity(tableVersion); var response = await this._container.CreateTransactionalBatch(new PartitionKey(this._clusterOptions.ClusterId)) .ReplaceItem(versionEntity.Id, versionEntity, new TransactionalBatchItemRequestOptions { IfMatchEtag = tableVersion.VersionEtag }) .CreateItem(siloEntity).ExecuteAsync(); return(response.IsSuccessStatusCode); } catch (CosmosException exc) { if (exc.StatusCode == HttpStatusCode.PreconditionFailed) { return(false); } throw; } }
protected async Task MembershipTable_ReadAll_Insert_ReadAll(bool extendedProtocol = true) { MembershipTableData data = await this.membershipTable.ReadAll(); this.logger?.Info("Membership.ReadAll returned TableVersion={tableVersion} Data={data}", data.Version, data); Assert.Equal(0, data.Members.Count); TableVersion newTableVersion = data.Version.Next(); MembershipEntry newEntry = CreateMembershipEntryForTest(); bool ok = await this.membershipTable.InsertRow(newEntry, newTableVersion); Assert.True(ok, "InsertRow failed"); data = await this.membershipTable.ReadAll(); this.logger?.Info("Membership.ReadAll returned TableVersion={tableVersion} Data={data}", data.Version, data); Assert.Equal(1, data.Members.Count); Assert.NotNull(data.Version.VersionEtag); if (extendedProtocol) { Assert.NotEqual(newTableVersion.VersionEtag, data.Version.VersionEtag); Assert.Equal(newTableVersion.Version, data.Version.Version); } var membershipEntry = data.Members[0].Item1; string eTag = data.Members[0].Item2; this.logger?.Info("Membership.ReadAll returned MembershipEntry ETag={eTag} Entry={entry}", eTag, membershipEntry); Assert.NotNull(eTag); Assert.NotNull(membershipEntry); }
public async Task <bool> UpdateRow(MembershipEntry entry, string etag, TableVersion tableVersion) { try { bool ret = false; if (string.IsNullOrEmpty(etag)) { etag = "0"; } var rentry = RedisMembershipEntry.Create(clusterId, entry, etag); var val = await database.StringGetAsync(clusterId); if (!val.IsNull) { RedisMembershipCollection collection = serializer.Deserialize <RedisMembershipCollection>(val); var items = collection.Where((x) => x.DeploymentId == clusterId && x.Address.ToParsableString() == rentry.Address.ToParsableString()); if (items != null && items.Count() > 0) { RedisMembershipEntry oldEntry = items.First(); rentry.LastIndex = oldEntry.LastIndex++; collection.Remove(oldEntry); collection.Add(rentry); ret = await database.StringSetAsync(clusterId, serializer.Serialize(collection)); } } return(ret); } catch (Exception ex) { logger?.LogError(ex, "Redis membership table key '{0}' failed update row.", clusterId); throw ex; } }
public async Task UpdateIAmAlive(MembershipEntry entry) { var key = entry.SiloAddress.ToString(); var tx = _db.CreateTransaction(); var tableVersionRowTask = tx.HashGetAsync(_clusterKey, TableVersionKey); var entryRowTask = tx.HashGetAsync(_clusterKey, key); if (!await tx.ExecuteAsync()) { throw new RedisClusteringException($"Unexpected transaction failure while reading key {key}"); } var entryRow = await entryRowTask; if (!entryRow.HasValue) { throw new RedisClusteringException($"Could not find a value for the key {key}"); } TableVersion tableVersion = GetTableVersionFromRow(await tableVersionRowTask).Next(); var existingEntry = Deserialize(entryRow); // Update only the IAmAliveTime property. existingEntry.IAmAliveTime = entry.IAmAliveTime; var result = await UpsertRowInternal(existingEntry, tableVersion, updateTableVersion : false, allowInsertOnly : false); if (result == UpsertResult.Conflict) { throw new RedisClusteringException($"Failed to update IAmAlive value for key {key} due to conflict"); } else if (result != UpsertResult.Success) { throw new RedisClusteringException($"Failed to update IAmAlive value for key {key} for an unknown reason"); } }
protected async Task MembershipTable_InsertRow(bool extendedProtocol = true) { var membershipEntry = CreateMembershipEntryForTest(); var data = await this.membershipTable.ReadAll(); Assert.NotNull(data); Assert.Equal(0, data.Members.Count); TableVersion nextTableVersion = data.Version.Next(); bool ok = await this.membershipTable.InsertRow(membershipEntry, nextTableVersion); Assert.True(ok, "InsertRow failed"); data = await this.membershipTable.ReadAll(); if (extendedProtocol) { Assert.Equal(1, data.Version.Version); } Assert.Equal(1, data.Members.Count); }
public static List <TableVersion> GetConfigVersions() { List <TableVersion> versions = new List <TableVersion>(); foreach (var version in ConfigDataBase.VersionConfig.Versions) { TableVersion ver = new TableVersion(); ver.tableName = version.TableName; ver.versionId = version.VersionText; versions.Add(ver); } foreach (var gmVersion in ConfigDataBase.GmVersionConfig.GmVersions) { TableVersion ver = new TableVersion(); ver.tableName = gmVersion.TableName; ver.versionId = gmVersion.VersionText; versions.Add(ver); } return(versions); }
public async Task <MembershipTableData> ReadRow(SiloAddress key) { var tx = _db.CreateTransaction(); var tableVersionRowTask = tx.HashGetAsync(_clusterKey, TableVersionKey); var entryRowTask = tx.HashGetAsync(_clusterKey, key.ToString()); if (!await tx.ExecuteAsync()) { throw new RedisClusteringException($"Unexpected transaction failure while reading key {key}"); } TableVersion tableVersion = GetTableVersionFromRow(await tableVersionRowTask); var entryRow = await entryRowTask; if (entryRow.HasValue) { var entry = Deserialize(entryRow); return(new MembershipTableData(Tuple.Create(entry, tableVersion.VersionEtag), tableVersion)); } else { return(new MembershipTableData(tableVersion)); } }
public async Task<bool> UpdateRow(MembershipEntry entry, string etag, TableVersion tableVersion) { try { if (logger.IsVerbose) logger.Verbose("UpdateRow entry = {0}, etag = {1}, table version = {2}", entry.ToFullString(), etag, tableVersion); var siloEntry = Convert(entry, tableManager.DeploymentId); var versionEntry = tableManager.CreateTableVersionEntry(tableVersion.Version); bool result = await tableManager.UpdateSiloEntryConditionally(siloEntry, etag, versionEntry, tableVersion.VersionEtag); if (result == false) logger.Warn(ErrorCode.AzureTable_24, $"Update failed due to contention on the table. Will retry. Entry {entry.ToFullString()}, eTag {etag}, table version = {tableVersion} "); return result; } catch (Exception exc) { logger.Warn(ErrorCode.AzureTable_25, $"Intermediate error updating entry {entry.ToFullString()} tableVersion {(tableVersion == null ? "null" : tableVersion.ToString())} to the table {tableManager.TableName}.", exc); throw; } }
/// <summary> /// UpdateRow /// </summary> /// <param name="entry"></param> /// <param name="etag"></param> /// <param name="tableVersion"></param> /// <returns></returns> public async Task <bool> UpdateRow( MembershipEntry entry, string etag, TableVersion tableVersion ) { try { if (entry == null) { throw new ArgumentNullException(nameof(entry)); } if (string.IsNullOrWhiteSpace(etag)) { throw new ArgumentNullException(nameof(etag)); } if (tableVersion == null) { throw new ArgumentNullException(nameof(tableVersion)); } using (var scope = _services.CreateScope()) { var db = scope .ServiceProvider .GetService <OrleansEFContext>(); var row = await db .Memberships .FirstOrDefaultAsync(a => a.DeploymentId == _clusterOptions.ClusterId && a.Address == entry.SiloAddress.Endpoint.Address.ToString() && a.Port == (uint)entry.SiloAddress.Endpoint.Port && a.Generation == entry.SiloAddress.Generation ); if (row == null) { throw new OrleansEFMembershipException.RowNotFound( entry.SiloAddress ); } OrleansEFMapper.Map(entry, row); await db.SaveChangesAsync(); _logger.Info( 0, "{0}: {1}", nameof(UpdateRow), $"updated silo {entry.SiloAddress.Endpoint.ToString()}" ); return(true); } } catch (Exception e) { _logger.Error(0, nameof(UpdateRow), e); throw; } }
public Task <bool> UpdateRow(MembershipEntry entry, string etag, TableVersion tableVersion) { return(manager.UpdateRow(entry, tableVersion, etag)); }
public InMemoryMembershipTable() { siloTable = new Dictionary <SiloAddress, Tuple <MembershipEntry, string> >(); lastETagCounter = 0; tableVersion = new TableVersion(0, NewETag()); }
public async Task<Boolean> InsertRow(MembershipEntry entry, TableVersion tableVersion) { try { //Use "0" as the eTag then Consul KV CAS will treat the operation as an insert and return false if the KV already exiats. var consulSiloRegistration = ConsulSiloRegistrationAssembler.FromMembershipEntry(_deploymentId, entry, "0"); var insertKV = ConsulSiloRegistrationAssembler.ToKVPair(consulSiloRegistration); var tryUpdate = await _consulClient.KV.CAS(insertKV); if (!tryUpdate.Response) { _logger.Verbose("ConsulMembershipProvider failed to insert the row because a registration already exists for silo {0}.", entry.SiloAddress); return false; } return true; } catch (Exception ex) { _logger.Info("ConsulMembershipProvider failed to insert registration for silo {0}; {1}.", entry.SiloAddress, ex); throw; } }
private MembershipTableData Convert(List<Tuple<SiloInstanceTableEntry, string>> entries) { try { var memEntries = new List<Tuple<MembershipEntry, string>>(); TableVersion tableVersion = null; foreach (var tuple in entries) { var tableEntry = tuple.Item1; if (tableEntry.RowKey.Equals(SiloInstanceTableEntry.TABLE_VERSION_ROW)) { tableVersion = new TableVersion(Int32.Parse(tableEntry.MembershipVersion), tuple.Item2); } else { try { MembershipEntry membershipEntry = Parse(tableEntry); memEntries.Add(new Tuple<MembershipEntry, string>(membershipEntry, tuple.Item2)); } catch (Exception exc) { logger.Error(ErrorCode.AzureTable_61, String.Format( "Intermediate error parsing SiloInstanceTableEntry to MembershipTableData: {0}. Ignoring this entry.", tableEntry), exc); } } } var data = new MembershipTableData(memEntries, tableVersion); return data; } catch (Exception exc) { logger.Error(ErrorCode.AzureTable_60, String.Format( "Intermediate error parsing SiloInstanceTableEntry to MembershipTableData: {0}.", Utils.EnumerableToString(entries, tuple => tuple.Item1.ToString())), exc); throw; } }
Task<bool> IMembershipTable.InsertRow(MembershipEntry entry, TableVersion tableVersion) { if (logger.IsVerbose3) logger.Verbose3(string.Format("SqlMembershipTable.InsertRow called with entry {0} and tableVersion {1}.", entry, tableVersion)); //The "tableVersion" parameter should always exist when inserting a row as Init should //have been called and membership version created and read. This is an optimization to //not to go through all the way to database to fail a conditional check on etag (which does //exist for the sake of robustness) as mandated by Orleans membership protocol. //Likewise, no update can be done without membership entry. if (entry == null) { if (logger.IsVerbose) logger.Verbose("SqlMembershipTable.InsertRow aborted due to null check. MembershipEntry is null."); throw new ArgumentNullException("entry"); } if (tableVersion == null) { if (logger.IsVerbose) logger.Verbose("SqlMembershipTable.InsertRow aborted due to null check. TableVersion is null "); throw new ArgumentNullException("tableVersion"); } try { var query = queryConstants.GetConstant(database.InvariantName, QueryKeys.InsertMembershipKey); return database.InsertMembershipRowAsync(query, deploymentId, entry, tableVersion); } catch(Exception ex) { if (logger.IsVerbose) logger.Verbose("SqlMembershipTable.InsertRow failed: {0}", ex); throw; } }
async Task<bool> IMembershipTable.UpdateRow(MembershipEntry entry, string etag, TableVersion tableVersion) { using (var conn = new SqlConnection(connectionString)) { conn.Open(); using (var tx = conn.BeginTransaction()) { if (tableVersion == null || await UpdateTableVersion(tableVersion, conn, tx)) { var command = new SqlCommand(UPDATE_ROW, conn, tx); ConvertToRow(entry, command, this.deploymentId); command.Parameters.Add(new SqlParameter { ParameterName = "@etag", DbType = DbType.String, Value = etag }); command.Parameters.Add(new SqlParameter { ParameterName = "@newetag", DbType = DbType.String, Value = NewEtag() }); var result = await command.ExecuteNonQueryAsync(); tx.Commit(); return result > 0; } } return false; } }
public async Task<Boolean> UpdateRow(MembershipEntry entry, String etag, TableVersion tableVersion) { //Update Silo Liveness try { var siloRegistration = ConsulSiloRegistrationAssembler.FromMembershipEntry(_deploymentId, entry, etag); var updateKV = ConsulSiloRegistrationAssembler.ToKVPair(siloRegistration); //If the KV.CAS() call returns false then the update failed var tryUpdate = await _consulClient.KV.CAS(updateKV); if (!tryUpdate.Response) { _logger.Verbose("ConsulMembershipProvider failed the CAS check when updating the registration for silo {0}.", entry.SiloAddress); return false; } return true; } catch (Exception ex) { _logger.Info("ConsulMembershipProvider failed to update the registration for silo {0}: {1}.", entry.SiloAddress, ex); throw; } }
public Task <bool> InsertRow(MembershipEntry entry, TableVersion tableVersion) { return(UpdateRow(entry, "", tableVersion)); }
Task<bool> IMembershipTable.InsertRow(MembershipEntry entry, TableVersion tableVersion) { logger.Verbose3(string.Format("SqlMembershipTable.InsertRow called with entry {0} and tableVersion {1}.", entry, tableVersion)); //The "tableVersion" parameter should always exist when inserting a row as Init should //have been called and membership version created and read. This is an optimization to //not to go through all the way to database to fail a conditional check on etag (which does //exist for the sake of robustness) as mandated by Orleans membership protocol. //Likewise, no update can be done without membership entry. if(tableVersion == null || entry == null) { logger.Verbose("SqlMembershipTable.InsertRow aborted due to null check. Is null MembershipEntry = {0}, is null TableVersion = {1}", entry == null, tableVersion == null); return Task.FromResult(false); } try { return database.InsertMembershipRowAsync(deploymentId, entry, tableVersion); } catch(Exception ex) { logger.Verbose("SqlMembershipTable.InsertRow failed: {0}", ex); throw; } }
public Task <bool> InsertRow(MembershipEntry entry, TableVersion tableVersion) { return(manager.InsertRow(entry, tableVersion)); }
public Task <bool> UpdateRow(MembershipEntry entry, string etag, TableVersion tableVersion) => this.grain.UpdateRow(entry, etag, tableVersion);
/// <summary> /// Updates membership row data. /// </summary> /// <param name="deploymentId">The deployment with which to insert row.</param> /// <param name="etag">The etag of which to use to check if the membership data being updated is not stale.</param> /// <param name="membershipEntry">The membership data to used to update database.</param> /// <param name="version">The membership version used to update database.</param> /// <returns><em>TRUE</em> if update SUCCEEDS. <em>FALSE</em> ot</returns> internal async Task<bool> UpdateMembershipRowAsync(string deploymentId, string etag, MembershipEntry membershipEntry, TableVersion version) { var ret = await storage.ReadAsync(orleansQueries.UpdateMembershipKey, command => { var siloIdParameter = CreateDeploymentIdParameter(command, deploymentId); command.Parameters.Add(siloIdParameter); var versionEtagParameter = CreateVersionEtagParameter(command, version.VersionEtag); command.Parameters.Add(versionEtagParameter); //The insert membership row part. var etagParameter = CreateEtagParameter(command, etag); command.Parameters.Add(etagParameter); var addressParameter = CreateAddressParameter(command, membershipEntry.SiloAddress.Endpoint.Address); command.Parameters.Add(addressParameter); var portParameter = CreatePortParameter(command, membershipEntry.SiloAddress.Endpoint.Port); command.Parameters.Add(portParameter); var generationParameter = CreateGenerationParameter(command, membershipEntry.SiloAddress.Generation); command.Parameters.Add(generationParameter); var hostNameParameter = CreateHostNameParameter(command, membershipEntry.HostName); command.Parameters.Add(hostNameParameter); var statusParameter = CreateStatusParameter(command, membershipEntry.Status); command.Parameters.Add(statusParameter); var proxyPortParameter = CreateProxyPortParameter(command, membershipEntry.ProxyPort); command.Parameters.Add(proxyPortParameter); var roleNameParameter = CreateRoleNameParameter(command, membershipEntry.RoleName); command.Parameters.Add(roleNameParameter); var instanceNameParameter = CreateInstanceNameParameter(command, membershipEntry.InstanceName); command.Parameters.Add(instanceNameParameter); var updateZoneParameter = CreateUpdateZoneParameter(command, membershipEntry.UpdateZone); command.Parameters.Add(updateZoneParameter); var faultZoneParameter = CreateFaultZoneParameter(command, membershipEntry.FaultZone); command.Parameters.Add(faultZoneParameter); var startTimeParameter = CreateStartTimeParameter(command, membershipEntry.StartTime); command.Parameters.Add(startTimeParameter); var iAmAliveTimeParameter = CreateIAmAliveTimeParameter(command, membershipEntry.IAmAliveTime); command.Parameters.Add(iAmAliveTimeParameter); var suspectingSilosParameter = CreateSuspectingSilosParameter(command, membershipEntry); command.Parameters.Add(suspectingSilosParameter); var suspectingTimesParameter = CreateSuspectingTimesParameter(command, membershipEntry); command.Parameters.Add(suspectingTimesParameter); }, (selector, resultSetCount, cancellationToken) => { return Task.FromResult(selector.GetBoolean(0)); }).ConfigureAwait(continueOnCapturedContext: false); return ret.First(); }
/// <summary> /// Updates membership row data. /// </summary> /// <param name="storage">The storage to use.</param> /// <param name="query">The query to use.</param> /// <param name="deploymentId">The deployment with which to insert row.</param> /// <param name="etag">The etag of which to use to check if the membership data being updated is not stale.</param> /// <param name="membershipEntry">The membership data to used to update database.</param> /// <param name="version">The membership version used to update database.</param> /// <returns><em>TRUE</em> if update SUCCEEDS. <em>FALSE</em> ot</returns> internal static async Task<bool> UpdateMembershipRowAsync(this IRelationalStorage storage, string query, string deploymentId, string etag, MembershipEntry membershipEntry, TableVersion version) { var ret = await storage.ReadAsync(query, command => { var direction = ParameterDirection.Input; var siloIdParameter = CreateDeploymentIdParameter(command, deploymentId, direction); command.Parameters.Add(siloIdParameter); var versionParameter = CreateVersionParameter(command, version.Version, direction); command.Parameters.Add(versionParameter); var versionEtagParameter = CreateVersionEtagParameter(command, version.VersionEtag, direction); command.Parameters.Add(versionEtagParameter); //The insert membership row part. var etagParameter = CreateEtagParameter(command, etag, direction); command.Parameters.Add(etagParameter); var addressParameter = CreateAddressParameter(command, membershipEntry.SiloAddress.Endpoint.Address, direction); command.Parameters.Add(addressParameter); var portParameter = CreatePortParameter(command, membershipEntry.SiloAddress.Endpoint.Port, direction); command.Parameters.Add(portParameter); var generationParameter = CreateGenerationParameter(command, membershipEntry.SiloAddress.Generation, direction); command.Parameters.Add(generationParameter); var hostNameParameter = CreateHostNameParameter(command, membershipEntry.HostName, direction); command.Parameters.Add(hostNameParameter); var statusParameter = CreateStatusParameter(command, membershipEntry.Status, direction); command.Parameters.Add(statusParameter); var proxyPortParameter = CreateProxyPortParameter(command, membershipEntry.ProxyPort, direction); command.Parameters.Add(proxyPortParameter); var roleNameParameter = CreateRoleNameParameter(command, membershipEntry.RoleName, direction); command.Parameters.Add(roleNameParameter); var instanceNameParameter = CreateInstanceNameParameter(command, membershipEntry.InstanceName, direction); command.Parameters.Add(instanceNameParameter); var updateZoneParameter = CreateUpdateZoneParameter(command, membershipEntry.UpdateZone, direction); command.Parameters.Add(updateZoneParameter); var faultZoneParameter = CreateFaultZoneParameter(command, membershipEntry.FaultZone, direction); command.Parameters.Add(faultZoneParameter); var startTimeParameter = CreateStartTimeParameter(command, membershipEntry.StartTime, direction); command.Parameters.Add(startTimeParameter); var iAmAliveTimeParameter = CreateIAmAliveTimeParameter(command, membershipEntry.IAmAliveTime, direction); command.Parameters.Add(iAmAliveTimeParameter); var suspectingSilosParameter = CreateSuspectingSilosParameter(command, membershipEntry, direction); command.Parameters.Add(suspectingSilosParameter); var suspectingTimesParameter = CreateSuspectingTimesParameter(command, membershipEntry, direction); command.Parameters.Add(suspectingTimesParameter); }, (selector, _) => { return selector.GetBoolean(0); }).ConfigureAwait(continueOnCapturedContext: false); return ret.First(); }
public async Task<bool> UpdateRow(MembershipEntry entry, string etag, TableVersion tableVersion) { try { if (logger.IsVerbose) logger.Verbose("UpdateRow entry = {0}, etag = {1}", entry.ToFullString(), etag); var siloEntry = Convert(entry); int currentEtag = 0; if (!int.TryParse(etag, out currentEtag)) { logger.Warn(ErrorCode.MembershipBase, $"Update failed. Invalid ETag value. Will retry. Entry {entry.ToFullString()}, eTag {etag}"); return false; } siloEntry.ETag = currentEtag + 1; bool result; try { var conditionalValues = new Dictionary<string, AttributeValue> { { CURRENT_ETAG_ALIAS, new AttributeValue { N = etag } } }; var etagConditionalExpression = $"{SiloInstanceRecord.ETAG_PROPERTY_NAME} = {CURRENT_ETAG_ALIAS}"; await storage.UpsertEntryAsync(TABLE_NAME_DEFAULT_VALUE, siloEntry.GetKeys(), siloEntry.GetFields(), etagConditionalExpression, conditionalValues); result = true; } catch (ConditionalCheckFailedException) { result = false; logger.Warn(ErrorCode.MembershipBase, $"Update failed due to contention on the table. Will retry. Entry {entry.ToFullString()}, eTag {etag}"); } return result; } catch (Exception exc) { logger.Warn(ErrorCode.MembershipBase, $"Intermediate error updating entry {entry.ToFullString()} to the table {TABLE_NAME_DEFAULT_VALUE}.", exc); throw; } }
private async Task<bool> UpdateTableVersion(TableVersion version, SqlConnection conn, SqlTransaction tx) { var read = new SqlCommand(READ_VERSION, conn, tx); read.Parameters.Add(new SqlParameter { ParameterName = "@deploymentid", DbType = DbType.String, Value = deploymentId }); string query; using (var results = await read.ExecuteReaderAsync()) { query = (results.HasRows) ? UPDATE_VERSION_ROW : INSERT_VERSION_ROW; } var write = new SqlCommand(query, conn, tx); write.Parameters.Add(new SqlParameter { ParameterName = "@deploymentid", DbType = DbType.String, Value = deploymentId }); write.Parameters.Add(new SqlParameter { ParameterName = "@timestamp", DbType = DbType.DateTime, Value = DateTime.UtcNow }); write.Parameters.Add(new SqlParameter { ParameterName = "@version", DbType = DbType.Int64, Value = version.Version }); write.Parameters.Add(new SqlParameter { ParameterName = "@etag", DbType = DbType.String, Value = version.VersionEtag }); write.Parameters.Add(new SqlParameter { ParameterName = "@newetag", DbType = DbType.String, Value = NewEtag() }); return (await write.ExecuteNonQueryAsync()) > 0; }
public Task <bool> InsertRow(MembershipEntry entry, TableVersion tableVersion) => this.grain.InsertRow(entry, tableVersion);
Task<bool> IMembershipTable.UpdateRow(MembershipEntry entry, string etag, TableVersion tableVersion) { if (logger.IsVerbose3) logger.Verbose3(string.Format("IMembershipTable.UpdateRow called with entry {0}, etag {1} and tableVersion {2}.", entry, etag, tableVersion)); //The "tableVersion" parameter should always exist when updating a row as Init should //have been called and membership version created and read. This is an optimization to //not to go through all the way to database to fail a conditional check (which does //exist for the sake of robustness) as mandated by Orleans membership protocol. //Likewise, no update can be done without membership entry or an etag. if (entry == null) { if (logger.IsVerbose) logger.Verbose("SqlMembershipTable.UpdateRow aborted due to null check. MembershipEntry is null."); throw new ArgumentNullException("entry"); } if (etag == null) { if (logger.IsVerbose) logger.Verbose("SqlMembershipTable.UpdateRow aborted due to null check. etag is null."); throw new ArgumentNullException("etag"); } if (tableVersion == null) { if (logger.IsVerbose) logger.Verbose("SqlMembershipTable.UpdateRow aborted due to null check. TableVersion is null "); throw new ArgumentNullException("tableVersion"); } try { return orleansQueries.UpdateMembershipRowAsync(deploymentId, etag, entry, tableVersion); } catch(Exception ex) { if (logger.IsVerbose) logger.Verbose("SqlMembershipTable.UpdateRow failed: {0}", ex); throw; } }
public async Task <bool> UpsertRow(string deploymentId, MembershipEntry entry, string etag, TableVersion tableVersion) { var id = ReturnId(deploymentId, entry.SiloAddress); var document = MongoMembershipDocument.Create(entry, deploymentId, id); try { await Collection.ReplaceOneAsync(x => x.Id == id && x.Etag == etag, document, Upsert); return(true); } catch (MongoException ex) { if (ex.IsDuplicateKey()) { return(false); } throw; } }
public Task <bool> UpdateRow(MembershipEntry entry, string etag, TableVersion tableVersion) { return(Task.FromResult(true)); }
protected async Task MembershipTable_ReadRow_Insert_Read(bool extendedProtocol = true) { MembershipTableData data = await this.membershipTable.ReadAll(); this.logger?.Info("Membership.ReadAll returned TableVersion={tableVersion} Data={data}", data.Version, data); Assert.Equal(0, data.Members.Count); TableVersion newTableVersion = data.Version.Next(); MembershipEntry newEntry = CreateMembershipEntryForTest(); bool ok = await this.membershipTable.InsertRow(newEntry, newTableVersion); Assert.True(ok, "InsertRow failed"); ok = await this.membershipTable.InsertRow(newEntry, newTableVersion); Assert.False(ok, "InsertRow should have failed - same entry, old table version"); if (extendedProtocol) { ok = await this.membershipTable.InsertRow(CreateMembershipEntryForTest(), newTableVersion); Assert.False(ok, "InsertRow should have failed - new entry, old table version"); } data = await this.membershipTable.ReadAll(); if (extendedProtocol) { Assert.Equal(1, data.Version.Version); } TableVersion nextTableVersion = data.Version.Next(); ok = await this.membershipTable.InsertRow(newEntry, nextTableVersion); Assert.False(ok, "InsertRow should have failed - duplicate entry"); data = await this.membershipTable.ReadAll(); Assert.Equal(1, data.Members.Count); data = await this.membershipTable.ReadRow(newEntry.SiloAddress); if (extendedProtocol) { Assert.Equal(newTableVersion.Version, data.Version.Version); } this.logger?.Info("Membership.ReadRow returned TableVersion={tableVersion} Data={data}", data.Version, data); Assert.Equal(1, data.Members.Count); Assert.NotNull(data.Version.VersionEtag); if (extendedProtocol) { Assert.NotEqual(newTableVersion.VersionEtag, data.Version.VersionEtag); Assert.Equal(newTableVersion.Version, data.Version.Version); } var membershipEntry = data.Members[0].Item1; string eTag = data.Members[0].Item2; this.logger?.Info("Membership.ReadRow returned MembershipEntry ETag={eTag} Entry={entry}", eTag, membershipEntry); Assert.NotNull(eTag); Assert.NotNull(membershipEntry); }
public async Task<bool> InsertRow(MembershipEntry entry, TableVersion tableVersion) { try { if (logger.IsVerbose) logger.Verbose("InsertRow entry = {0}", entry.ToFullString()); var tableEntry = Convert(entry); bool result; try { var expression = $"attribute_not_exists({SiloInstanceRecord.DEPLOYMENT_ID_PROPERTY_NAME}) AND attribute_not_exists({SiloInstanceRecord.SILO_IDENTITY_PROPERTY_NAME})"; await storage.PutEntryAsync(TABLE_NAME_DEFAULT_VALUE, tableEntry.GetFields(true), expression); result = true; } catch (ConditionalCheckFailedException) { result = false; logger.Warn(ErrorCode.MembershipBase, $"Insert failed due to contention on the table. Will retry. Entry {entry.ToFullString()}"); } return result; } catch (Exception exc) { logger.Warn(ErrorCode.MembershipBase, $"Intermediate error inserting entry {entry.ToFullString()} to the table {TABLE_NAME_DEFAULT_VALUE}.", exc); throw; } }
protected async Task MembershipTable_UpdateRow(bool extendedProtocol = true) { var tableData = await this.membershipTable.ReadAll(); Assert.NotNull(tableData.Version); Assert.Equal(0, tableData.Version.Version); Assert.Equal(0, tableData.Members.Count); for (int i = 1; i < 10; i++) { var siloEntry = CreateMembershipEntryForTest(); siloEntry.SuspectTimes = new List <Tuple <SiloAddress, DateTime> > { new Tuple <SiloAddress, DateTime>(CreateSiloAddressForTest(), GetUtcNowWithSecondsResolution().AddSeconds(1)), new Tuple <SiloAddress, DateTime>(CreateSiloAddressForTest(), GetUtcNowWithSecondsResolution().AddSeconds(2)) }; TableVersion tableVersion = tableData.Version.Next(); this.logger?.Info("Calling InsertRow with Entry={entry} TableVersion={tableVersion}", siloEntry, tableVersion); bool ok = await this.membershipTable.InsertRow(siloEntry, tableVersion); Assert.True(ok, "InsertRow failed"); tableData = await this.membershipTable.ReadAll(); var etagBefore = tableData.Get(siloEntry.SiloAddress).Item2; Assert.NotNull(etagBefore); if (extendedProtocol) { this.logger?.Info("Calling UpdateRow with Entry={entry} correct eTag={eTag} old version={tableVersion}", siloEntry, etagBefore, tableVersion != null ? tableVersion.ToString() : "null"); ok = await this.membershipTable.UpdateRow(siloEntry, etagBefore, tableVersion); Assert.False(ok, $"row update should have failed - Table Data = {tableData}"); tableData = await this.membershipTable.ReadAll(); } tableVersion = tableData.Version.Next(); this.logger?.Info("Calling UpdateRow with Entry={entry} correct eTag={eTag} correct version={tableVersion}", siloEntry, etagBefore, tableVersion != null ? tableVersion.ToString() : "null"); ok = await this.membershipTable.UpdateRow(siloEntry, etagBefore, tableVersion); Assert.True(ok, $"UpdateRow failed - Table Data = {tableData}"); this.logger?.Info("Calling UpdateRow with Entry={entry} old eTag={eTag} old version={tableVersion}", siloEntry, etagBefore, tableVersion != null ? tableVersion.ToString() : "null"); ok = await this.membershipTable.UpdateRow(siloEntry, etagBefore, tableVersion); Assert.False(ok, $"row update should have failed - Table Data = {tableData}"); tableData = await this.membershipTable.ReadAll(); var tuple = tableData.Get(siloEntry.SiloAddress); //Assert.Equal(tuple.Item1.ToFullString(true), siloEntry.ToFullString(true)); var etagAfter = tuple.Item2; if (extendedProtocol) { this.logger?.Info("Calling UpdateRow with Entry={entry} correct eTag={eTag} old version={tableVersion}", siloEntry, etagAfter, tableVersion != null ? tableVersion.ToString() : "null"); ok = await this.membershipTable.UpdateRow(siloEntry, etagAfter, tableVersion); Assert.False(ok, $"row update should have failed - Table Data = {tableData}"); } tableData = await this.membershipTable.ReadAll(); etagBefore = etagAfter; etagAfter = tableData.Get(siloEntry.SiloAddress).Item2; Assert.Equal(etagBefore, etagAfter); Assert.NotNull(tableData.Version); if (extendedProtocol) { Assert.Equal(tableVersion.Version, tableData.Version.Version); } Assert.Equal(i, tableData.Members.Count); } }
public async Task <bool> UpdateRow(MembershipEntry entry, string etag, TableVersion tableVersion) { try { if (this.logger.IsEnabled(LogLevel.Debug)) { this.logger.Debug("UpdateRow entry = {0}, etag = {1}", entry.ToFullString(), etag); } var siloEntry = Convert(entry, tableVersion); if (!int.TryParse(etag, out var currentEtag)) { this.logger.Warn(ErrorCode.MembershipBase, $"Update failed. Invalid ETag value. Will retry. Entry {entry.ToFullString()}, eTag {etag}"); return(false); } siloEntry.ETag = currentEtag + 1; if (!TryCreateTableVersionRecord(tableVersion.Version, tableVersion.VersionEtag, out var versionEntry)) { this.logger.Warn(ErrorCode.MembershipBase, $"Update failed. Invalid ETag value. Will retry. Entry {entry.ToFullString()}, eTag {tableVersion.VersionEtag}"); return(false); } versionEntry.ETag++; bool result; try { var etagConditionalExpression = $"{SiloInstanceRecord.ETAG_PROPERTY_NAME} = {CURRENT_ETAG_ALIAS}"; var siloConditionalValues = new Dictionary <string, AttributeValue> { { CURRENT_ETAG_ALIAS, new AttributeValue { N = etag } } }; var siloEntryUpdate = new Update { TableName = this.options.TableName, Key = siloEntry.GetKeys(), ConditionExpression = etagConditionalExpression }; (siloEntryUpdate.UpdateExpression, siloEntryUpdate.ExpressionAttributeValues) = this.storage.ConvertUpdate(siloEntry.GetFields(), siloConditionalValues); var versionConditionalValues = new Dictionary <string, AttributeValue> { { CURRENT_ETAG_ALIAS, new AttributeValue { N = tableVersion.VersionEtag } } }; var versionEntryUpdate = new Update { TableName = this.options.TableName, Key = versionEntry.GetKeys(), ConditionExpression = etagConditionalExpression }; (versionEntryUpdate.UpdateExpression, versionEntryUpdate.ExpressionAttributeValues) = this.storage.ConvertUpdate(versionEntry.GetFields(), versionConditionalValues); await this.storage.WriteTxAsync(updates : new[] { siloEntryUpdate, versionEntryUpdate }); result = true; } catch (TransactionCanceledException canceledException) { if (canceledException.Message.Contains("ConditionalCheckFailed")) //not a good way to check for this currently { result = false; this.logger.Warn(ErrorCode.MembershipBase, $"Update failed due to contention on the table. Will retry. Entry {entry.ToFullString()}, eTag {etag}"); } else { throw; } } return(result); } catch (Exception exc) { this.logger.Warn(ErrorCode.MembershipBase, $"Intermediate error updating entry {entry.ToFullString()} to the table {this.options.TableName}.", exc); throw; } }
Task <bool> IMembershipTable.UpdateRow(MembershipEntry entry, string etag, TableVersion tableVersion) { return(session.ExecuteAsync(queries.UpdateMembership(entry, tableVersion.Version - 1)).ContinueWith(t => (bool)t.Result.First()["[applied]"])); }
public InMemoryMembershipTable() { siloTable = new Dictionary<SiloAddress, Tuple<MembershipEntry, string>>(); lastETagCounter = 0; tableVersion = new TableVersion(0, NewETag()); }
public Task <bool> InsertRow(MembershipEntry entry, TableVersion tableVersion) { return(Task.FromResult(true)); }
async Task <bool> IMembershipTable.UpdateRow(MembershipEntry entry, string etag, TableVersion tableVersion) { using (var conn = new SqlConnection(connectionString)) { conn.Open(); using (var tx = conn.BeginTransaction()) { if (tableVersion == null || await UpdateTableVersion(tableVersion, conn, tx)) { var command = new SqlCommand(UPDATE_ROW, conn, tx); ConvertToRow(entry, command, this.deploymentId); command.Parameters.Add(new SqlParameter { ParameterName = "@etag", DbType = DbType.String, Value = etag }); command.Parameters.Add(new SqlParameter { ParameterName = "@newetag", DbType = DbType.String, Value = NewEtag() }); var result = await command.ExecuteNonQueryAsync(); tx.Commit(); return(result > 0); } } return(false); } }
public async Task <bool> InsertRow(MembershipEntry entry, TableVersion tableVersion) { try { var siloEntity = this.ConvertToEntity(entry); var versionEntity = this.BuildVersionEntity(tableVersion); SiloEntity existentSiloEntry = default; try { existentSiloEntry = ((JObject)await this._kubeClient.GetNamespacedCustomObjectAsync( Constants.ORLEANS_GROUP, Constants.PROVIDER_MODEL_VERSION, this._namespace, SiloEntity.PLURAL, siloEntity.Metadata.Name ))?.ToObject <SiloEntity>(); } catch (HttpOperationException ex) { if (ex.Response.StatusCode != HttpStatusCode.NotFound) { throw; } } if (existentSiloEntry != null) { return(false); } var currentVersionEntity = await this.GetClusterVersion(); if (currentVersionEntity == null || currentVersionEntity.ClusterVersion == versionEntity.ClusterVersion) { return(false); } var updatedVersionEntity = await this._kubeClient.ReplaceNamespacedCustomObjectAsync( versionEntity, Constants.ORLEANS_GROUP, Constants.PROVIDER_MODEL_VERSION, this._namespace, ClusterVersionEntity.PLURAL, versionEntity.Metadata.Name ); if (updatedVersionEntity == null) { return(false); } var createdSiloEntity = await this._kubeClient.CreateNamespacedCustomObjectAsync( siloEntity, Constants.ORLEANS_GROUP, Constants.PROVIDER_MODEL_VERSION, this._namespace, SiloEntity.PLURAL ); return(createdSiloEntity != null); } catch (InvalidOperationException) { return(false); } catch (Exception exc) { this._logger?.LogError(exc, "Unable to insert Silo Entry."); throw; } }
public async Task <bool> InsertRow(MembershipEntry entry, TableVersion tableVersion) { try { if (this.logger.IsEnabled(LogLevel.Debug)) { this.logger.Debug("InsertRow entry = {0}", entry.ToFullString()); } var tableEntry = Convert(entry, tableVersion); if (!TryCreateTableVersionRecord(tableVersion.Version, tableVersion.VersionEtag, out var versionEntry)) { this.logger.Warn(ErrorCode.MembershipBase, $"Insert failed. Invalid ETag value. Will retry. Entry {entry.ToFullString()}, eTag {tableVersion.VersionEtag}"); return(false); } versionEntry.ETag++; bool result; try { var notExistConditionExpression = $"attribute_not_exists({SiloInstanceRecord.DEPLOYMENT_ID_PROPERTY_NAME}) AND attribute_not_exists({SiloInstanceRecord.SILO_IDENTITY_PROPERTY_NAME})"; var tableEntryInsert = new Put { Item = tableEntry.GetFields(true), ConditionExpression = notExistConditionExpression, TableName = this.options.TableName }; var conditionalValues = new Dictionary <string, AttributeValue> { { CURRENT_ETAG_ALIAS, new AttributeValue { N = tableVersion.VersionEtag } } }; var etagConditionalExpression = $"{SiloInstanceRecord.ETAG_PROPERTY_NAME} = {CURRENT_ETAG_ALIAS}"; var versionEntryUpdate = new Update { TableName = this.options.TableName, Key = versionEntry.GetKeys(), ConditionExpression = etagConditionalExpression }; (versionEntryUpdate.UpdateExpression, versionEntryUpdate.ExpressionAttributeValues) = this.storage.ConvertUpdate(versionEntry.GetFields(), conditionalValues); await this.storage.WriteTxAsync(new[] { tableEntryInsert }, new[] { versionEntryUpdate }); result = true; } catch (TransactionCanceledException canceledException) { if (canceledException.Message.Contains("ConditionalCheckFailed")) //not a good way to check for this currently { result = false; this.logger.Warn(ErrorCode.MembershipBase, $"Insert failed due to contention on the table. Will retry. Entry {entry.ToFullString()}"); } else { throw; } } return(result); } catch (Exception exc) { this.logger.Warn(ErrorCode.MembershipBase, $"Intermediate error inserting entry {entry.ToFullString()} to the table {this.options.TableName}.", exc); throw; } }