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 = sqlConnectionFactory.OpenNewConnection(connectionString)) { 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 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); }
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)); } } } } } }
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); }
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 AdaptivePollingReceiver( IReceiveStrategy receiveStrategy, TableBasedQueue queue, Action <TransportMessage, Exception> endProcessMessage, RepeatedFailuresOverTimeCircuitBreaker circuitBreaker, TransportNotifications transportNotifications) : base(circuitBreaker) { this.receiveStrategy = receiveStrategy; this.queue = queue; this.endProcessMessage = endProcessMessage; this.transportNotifications = transportNotifications; }
public AdaptivePollingReceiver( IReceiveStrategy receiveStrategy, TableBasedQueue queue, Action <TransportMessage, Exception> endProcessMessage, RepeatedFailuresOverTimeCircuitBreaker circuitBreaker, TransportNotifications transportNotifications) : base(queue.ToString(), circuitBreaker, transportNotifications, TimeSpan.FromMilliseconds(SlowTaskThresholdInMilliseconds)) { this.receiveStrategy = receiveStrategy; this.queue = queue; this.endProcessMessage = endProcessMessage; this.transportNotifications = transportNotifications; }
public AmbientTransactionReceiveStrategy(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; transactionOptions = new TransactionOptions { IsolationLevel = transactionSettings.IsolationLevel, Timeout = transactionSettings.TransactionTimeout }; }
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, sqlConnectionFactory, connectionStore, settings)); } return(new AmbientTransactionReceiveStrategy(localConnectionParams.ConnectionString, errorQueue, tryProcessMessageCallback, sqlConnectionFactory, connectionStore, settings)); } return(new NoTransactionReceiveStrategy(localConnectionParams.ConnectionString, errorQueue, tryProcessMessageCallback, sqlConnectionFactory)); }
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(); } }
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 ExpiredMessagesPurger(TableBasedQueue queue, Func <SqlConnection> openConnection, PurgeExpiredMessagesParams parameters) { this.queue = queue; this.openConnection = openConnection; this.parameters = parameters; }