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));
            });
        }
Esempio n. 6
0
        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);
                            }
                        }
                    }
                }
            }
        }
Esempio n. 8
0
        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);
        }
Esempio n. 15
0
        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);
 }
Esempio n. 17
0
        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);
     });
 }
Esempio n. 23
0
        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));
            }
        }