public async Task Purge(TableBasedQueue queue, CancellationToken cancellationToken) { if (!enable) { Logger.DebugFormat("Purging expired messages on startup is not enabled for {0}.", queue); return; } Logger.DebugFormat("Starting a new expired message purge task for table {0}.", queue); var totalPurgedRowsCount = 0; try { using (var connection = await openConnection(queue).ConfigureAwait(false)) { var continuePurging = true; while (continuePurging && !cancellationToken.IsCancellationRequested) { var purgedRowsCount = await queue.PurgeBatchOfExpiredMessages(connection, purgeBatchSize).ConfigureAwait(false); totalPurgedRowsCount += purgedRowsCount; continuePurging = purgedRowsCount == purgeBatchSize; } } Logger.DebugFormat("{0} expired messages were successfully purged from table {1}", totalPurgedRowsCount, queue); } catch { Logger.WarnFormat("Purging expired messages from table {0} failed after purging {1} messages.", queue, totalPurgedRowsCount); throw; } }
public virtual async Task <int> Purge(TableBasedQueue queue) { using (var connection = await connectionFactory.OpenNewConnection().ConfigureAwait(false)) { return(await queue.Purge(connection).ConfigureAwait(false)); } }
public void Init(TableBasedQueue inputQueue, TableBasedQueue errorQueue, Func <MessageContext, Task> onMessage, Func <ErrorContext, Task <ErrorHandleResult> > onError, CriticalError criticalError) { InputQueue = inputQueue; ErrorQueue = errorQueue; this.onMessage = onMessage; this.onError = onError; this.criticalError = criticalError; }
async Task VerifyHeadersColumnType(TableBasedQueue queue) { try { using (var connection = await openConnection(queue).ConfigureAwait(false)) { var columnType = await queue.CheckHeadersColumnType(connection).ConfigureAwait(false); if (string.Equals(columnType, "varchar", StringComparison.OrdinalIgnoreCase)) { Logger.Warn($"Table {queue.Name} stores headers in a non Unicode-compatible column (varchar).{Environment.NewLine}This may lead to data loss when sending non-ASCII characters in headers. SQL Server transport 3.1 and newer can take advantage of the nvarchar column type for headers. Please change the column type in the database."); } } } catch (Exception ex) { Logger.WarnFormat("Checking indexes on table {0} failed. Exception: {1}", queue, ex); } }
async Task VerifyExpiredIndex(TableBasedQueue queue) { try { using (var connection = await openConnection(queue).ConfigureAwait(false)) { var indexExists = await queue.CheckExpiresIndexPresence(connection).ConfigureAwait(false); if (!indexExists) { Logger.Warn($@"Table {queue.Name} does not contain index 'Index_Expires'.{Environment.NewLine}Adding this index will speed up the process of purging expired messages from the queue. Please consult the documentation for further information."); } } } catch (Exception ex) { Logger.WarnFormat("Checking indexes on table {0} failed. Exception: {1}", queue, ex); } }
public async Task <int> Peek(TableBasedQueue inputQueue, RepeatedFailuresOverTimeCircuitBreaker circuitBreaker, CancellationToken cancellationToken) { var messageCount = 0; try { using (var scope = new TransactionScope(TransactionScopeOption.RequiresNew, new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted }, TransactionScopeAsyncFlowOption.Enabled)) using (var connection = await connectionFactory.OpenNewConnection().ConfigureAwait(false)) { messageCount = await inputQueue.TryPeek(connection, cancellationToken).ConfigureAwait(false); circuitBreaker.Success(); if (messageCount == 0) { Logger.Debug($"Input queue empty. Next peek operation will be delayed for {settings.Delay}."); await Task.Delay(settings.Delay, cancellationToken).ConfigureAwait(false); } scope.Complete(); } } catch (OperationCanceledException) { //Graceful shutdown } catch (SqlException e) when(cancellationToken.IsCancellationRequested) { Logger.Debug("Exception thown while performing cancellation", e); } catch (Exception ex) { Logger.Warn("Sql peek operation failed", ex); await circuitBreaker.Failure(ex).ConfigureAwait(false); } return(messageCount); }
public async Task PerformInspection(TableBasedQueue queue) { await VerifyExpiredIndex(queue).ConfigureAwait(false); await VerifyHeadersColumnType(queue).ConfigureAwait(false); }