public NoTransactionReceiveStrategy(string connectionString, TableBasedQueue errorQueue, Func<TransportMessage, bool> tryProcessMessageCallback, ConnectionFactory sqlConnectionFactory) { this.connectionString = connectionString; this.errorQueue = errorQueue; this.tryProcessMessageCallback = tryProcessMessageCallback; this.sqlConnectionFactory = sqlConnectionFactory; }
public ReceiveResult TryReceiveFrom(TableBasedQueue queue) { MessageReadResult readResult; using (var connection = new SqlConnection(connectionString)) { connection.Open(); readResult = queue.TryReceive(connection); if (readResult.IsPoison) { errorQueue.Send(readResult.DataRecord, connection); return ReceiveResult.NoMessage(); } } if (!readResult.Successful) { return ReceiveResult.NoMessage(); } var result = ReceiveResult.Received(readResult.Message); try { tryProcessMessageCallback(readResult.Message); return result; } catch (Exception ex) { return result.FailedProcessing(ex); } }
public void Send(TransportMessage message, SendOptions sendOptions) { Address destination = null; try { destination = DetermineDestination(sendOptions); var connectionInfo = connectionStringProvider.GetForDestination(sendOptions.Destination); var queue = new TableBasedQueue(destination, connectionInfo.Schema); if (sendOptions.EnlistInReceiveTransaction) { SqlTransaction currentTransaction; if (connectionStore.TryGetTransaction(connectionInfo.ConnectionString, out currentTransaction)) { queue.Send(message, sendOptions, currentTransaction.Connection, currentTransaction); } else { SqlConnection currentConnection; if (connectionStore.TryGetConnection(connectionInfo.ConnectionString, out currentConnection)) { queue.Send(message, sendOptions, currentConnection); } else { using (var connection = sqlConnectionFactory.OpenNewConnection(connectionInfo.ConnectionString)) { queue.Send(message, sendOptions, connection); } } } } else { // Suppress so that even if DTC is on, we won't escalate using (var tx = new TransactionScope(TransactionScopeOption.Suppress)) { using (var connection = sqlConnectionFactory.OpenNewConnection(connectionInfo.ConnectionString)) { queue.Send(message, sendOptions, connection); } tx.Complete(); } } } catch (SqlException ex) { if (ex.Number == 208) { ThrowQueueNotFoundException(destination, ex); } ThrowFailedToSendException(destination, ex); } catch (Exception ex) { ThrowFailedToSendException(destination, ex); } }
public NativeTransactionReceiveStrategy(string connectionString, TableBasedQueue errorQueue, Func<TransportMessage, bool> tryProcessMessageCallback, PipelineExecutor pipelineExecutor, TransactionSettings transactionSettings) { this.pipelineExecutor = pipelineExecutor; this.tryProcessMessageCallback = tryProcessMessageCallback; this.errorQueue = errorQueue; this.connectionString = connectionString; isolationLevel = GetSqlIsolationLevel(transactionSettings.IsolationLevel); }
static async Task ReceiveWithLongHandling(TableBasedQueue tableBasedQueue) { await ExecuteInTransactionScope(async c => { await tableBasedQueue.TryReceive(c, null); await Task.Delay(TimeSpan.FromSeconds(ReceiveDelayInSeconds)); }); }
public async Task SetUp() { var addressParser = new QueueAddressTranslator("nservicebus", "dbo", null, null); await ResetQueue(addressParser); queue = new TableBasedQueue(addressParser.Parse(QueueTableName).QualifiedTableName, QueueTableName); }
public ReceiveResult TryReceiveFrom(TableBasedQueue queue) { using (var connection = new SqlConnection(connectionString)) { connection.Open(); using (pipelineExecutor.SetConnection(connectionString, connection)) { using (var transaction = connection.BeginTransaction(isolationLevel)) { using (pipelineExecutor.SetTransaction(connectionString, transaction)) { MessageReadResult readResult; try { readResult = queue.TryReceive(connection, transaction); } catch (Exception) { transaction.Rollback(); throw; } if (readResult.IsPoison) { errorQueue.Send(readResult.DataRecord, connection, transaction); transaction.Commit(); return ReceiveResult.NoMessage(); } if (!readResult.Successful) { transaction.Commit(); return ReceiveResult.NoMessage(); } var result = ReceiveResult.Received(readResult.Message); try { if (tryProcessMessageCallback(result.Message)) { transaction.Commit(); } else { transaction.Rollback(); } return result; } catch (Exception ex) { transaction.Rollback(); return result.FailedProcessing(ex); } } } } } }
Task PurgeOutputQueue(QueueAddressTranslator addressParser) { purger = new QueuePurger(sqlConnectionFactory); var queueAddress = addressParser.Parse(validAddress); queue = new TableBasedQueue(queueAddress.QualifiedTableName, queueAddress.Address, true); return(purger.Purge(queue)); }
public NativeTransactionReceiveStrategy(string connectionString, TableBasedQueue errorQueue, Func<TransportMessage, bool> tryProcessMessageCallback, ConnectionFactory sqlConnectionFactory, IConnectionStore connectionStore, TransactionSettings transactionSettings) { this.tryProcessMessageCallback = tryProcessMessageCallback; this.errorQueue = errorQueue; this.connectionString = connectionString; this.sqlConnectionFactory = sqlConnectionFactory; this.connectionStore = connectionStore; isolationLevel = GetSqlIsolationLevel(transactionSettings.IsolationLevel); }
static async Task SendMessage(TableBasedQueue tableBasedQueue) { await ExecuteInTransactionScope(async c => { var message = new OutgoingMessage(Guid.NewGuid().ToString(), new Dictionary <string, string>(), new byte[0]); await tableBasedQueue.Send(message, TimeSpan.MaxValue, c, null); }); }
Task PurgeOutputQueue(QueueAddressParser addressParser) { purger = new QueuePurger(sqlConnectionFactory); var queueAddress = addressParser.Parse(validAddress); queue = new TableBasedQueue(queueAddress); return(purger.Purge(queue)); }
Task PurgeOutputQueue(QueueAddressTranslator addressParser, CancellationToken cancellationToken = default) { purger = new QueuePurger(sqlConnectionFactory); var queueAddress = addressParser.Parse(ValidAddress); queue = new TableBasedQueue(queueAddress.QualifiedTableName, queueAddress.Address, true); return(purger.Purge(queue, cancellationToken)); }
public AmbientTransactionReceiveStrategy(string connectionString, TableBasedQueue errorQueue, Func<TransportMessage, bool> tryProcessMessageCallback, PipelineExecutor pipelineExecutor, TransactionSettings transactionSettings) { this.pipelineExecutor = pipelineExecutor; this.tryProcessMessageCallback = tryProcessMessageCallback; this.errorQueue = errorQueue; this.connectionString = connectionString; transactionOptions = new TransactionOptions { IsolationLevel = transactionSettings.IsolationLevel, Timeout = transactionSettings.TransactionTimeout }; }
public async Task SetUp() { var addressParser = new QueueAddressTranslator("nservicebus", "dbo", null, null); var connectionString = Environment.GetEnvironmentVariable("SqlServerTransportConnectionString") ?? @"Data Source=.\SQLEXPRESS;Initial Catalog=nservicebus;Integrated Security=True"; sqlConnectionFactory = SqlConnectionFactory.Default(connectionString); await ResetQueue(addressParser, sqlConnectionFactory); queue = new TableBasedQueue(addressParser.Parse(QueueTableName).QualifiedTableName, QueueTableName, false); }
static async Task TryPeekQueueSize(TableBasedQueue tableBasedQueue, SqlConnectionFactory sqlConnectionFactory) { using (var scope = new TransactionScope(TransactionScopeOption.Suppress, TransactionScopeAsyncFlowOption.Enabled)) { using (var connection = await sqlConnectionFactory.OpenNewConnection()) using (var tx = connection.BeginTransaction()) { await tableBasedQueue.TryPeek(connection, tx, CancellationToken.None, PeekTimeoutInSeconds); scope.Complete(); } } }
public IReceiveStrategy Create(TransactionSettings settings, Func<TransportMessage, bool> tryProcessMessageCallback) { var errorQueue = new TableBasedQueue(errorQueueAddress, localConnectionParams.Schema); if (settings.IsTransactional) { if (settings.SuppressDistributedTransactions) { return new NativeTransactionReceiveStrategy(localConnectionParams.ConnectionString, errorQueue, tryProcessMessageCallback, pipelineExecutor, settings); } return new AmbientTransactionReceiveStrategy(localConnectionParams.ConnectionString, errorQueue, tryProcessMessageCallback, pipelineExecutor, settings); } return new NoTransactionReceiveStrategy(localConnectionParams.ConnectionString, errorQueue, tryProcessMessageCallback); }
static async Task TryPeekQueueSize(TableBasedQueue tableBasedQueue, SqlConnectionFactory sqlConnectionFactory, CancellationToken cancellationToken = default) { using (var scope = new TransactionScope(TransactionScopeOption.Suppress, TransactionScopeAsyncFlowOption.Enabled)) { using (var connection = await sqlConnectionFactory.OpenNewConnection(cancellationToken)) using (var tx = connection.BeginTransaction()) { tableBasedQueue.FormatPeekCommand(100); await tableBasedQueue.TryPeek(connection, tx, PeekTimeoutInSeconds, cancellationToken); scope.Complete(); } } }
static async Task SendMessage(TableBasedQueue tableBasedQueue, SqlConnectionFactory sqlConnectionFactory) { using (var scope = new TransactionScope(TransactionScopeOption.Suppress, TransactionScopeAsyncFlowOption.Enabled)) { using (var connection = await sqlConnectionFactory.OpenNewConnection()) using (var tx = connection.BeginTransaction()) { var message = new OutgoingMessage(Guid.NewGuid().ToString(), new Dictionary <string, string>(), new byte[0]); await tableBasedQueue.Send(message, TimeSpan.MaxValue, connection, tx); tx.Commit(); scope.Complete(); } } }
static async Task ReceiveWithLongHandling(TableBasedQueue tableBasedQueue, SqlConnectionFactory sqlConnectionFactory) { using (var scope = new TransactionScope(TransactionScopeOption.Suppress, TransactionScopeAsyncFlowOption.Enabled)) { using (var connection = await sqlConnectionFactory.OpenNewConnection()) using (var tx = connection.BeginTransaction()) { await tableBasedQueue.TryReceive(connection, tx); await Task.Delay(TimeSpan.FromSeconds(ReceiveDelayInSeconds)); tx.Commit(); scope.Complete(); } } }
public ReceiveResult TryReceiveFrom(TableBasedQueue queue) { using (var scope = new TransactionScope(TransactionScopeOption.Required, transactionOptions)) { using (var connection = new SqlConnection(connectionString)) { connection.Open(); using (pipelineExecutor.SetConnection(connectionString, connection)) { var readResult = queue.TryReceive(connection); if (readResult.IsPoison) { errorQueue.Send(readResult.DataRecord, connection); scope.Complete(); return ReceiveResult.NoMessage(); } if (!readResult.Successful) { scope.Complete(); return ReceiveResult.NoMessage(); } var result = ReceiveResult.Received(readResult.Message); try { if (tryProcessMessageCallback(readResult.Message)) { scope.Complete(); scope.Dispose(); // We explicitly calling Dispose so that we force any exception to not bubble, eg Concurrency/Deadlock exception. } return result; } catch (Exception ex) { return result.FailedProcessing(ex); } } } } }
/// <summary> /// Initializes the <see cref="IDequeueMessages" />. /// </summary> /// <param name="primaryAddress">The address to listen on.</param> /// <param name="transactionSettings"> /// The <see cref="TransactionSettings" /> to be used by <see cref="IDequeueMessages" />. /// </param> /// <param name="tryProcessMessage">Called when a message has been dequeued and is ready for processing.</param> /// <param name="endProcessMessage"> /// Needs to be called by <see cref="IDequeueMessages" /> after the message has been processed regardless if the /// outcome was successful or not. /// </param> public void Init(Address primaryAddress, TransactionSettings transactionSettings, Func<TransportMessage, bool> tryProcessMessage, Action<TransportMessage, Exception> endProcessMessage) { queuePurger.Purge(primaryAddress); secondaryReceiveSettings = secondaryReceiveConfiguration.GetSettings(primaryAddress.Queue); var receiveStrategy = receiveStrategyFactory.Create(transactionSettings, tryProcessMessage); primaryReceiver = new AdaptivePollingReceiver(receiveStrategy, new TableBasedQueue(primaryAddress, locaConnectionParams.Schema), endProcessMessage, circuitBreaker, transportNotifications); if (secondaryReceiveSettings.IsEnabled) { var secondaryQueue = new TableBasedQueue(SecondaryReceiveSettings.ReceiveQueue.GetTableName(), locaConnectionParams.Schema); secondaryReceiver = new AdaptivePollingReceiver(receiveStrategy, secondaryQueue, endProcessMessage, circuitBreaker, transportNotifications); } else { secondaryReceiver = new NullExecutor(); } }
static async Task TryPeekQueueSize(TableBasedQueue tableBasedQueue) { await ExecuteInTransactionScope(async c => { await tableBasedQueue.TryPeek(c, CancellationToken.None, PeekTimeoutInSeconds); }); }
async Task <int> RunTest(Type contextProviderType, DispatchConsistency dispatchConsistency, TableBasedQueue queue, QueuePurger purger, CancellationToken cancellationToken) { using (var contextProvider = CreateContext(contextProviderType, sqlConnectionFactory)) { // Run with Recoverable column in place var operations = new TransportOperations(CreateTransportOperation(id: "1", destination: QueueName, consistency: dispatchConsistency)); await dispatcher.Dispatch(operations, contextProvider.TransportTransaction, cancellationToken); contextProvider.Complete(); return(await purger.Purge(queue, cancellationToken)); } }