Exemplo n.º 1
0
 public ReplyHandlerStep(ConcurrentDictionary<string, TimedMessage> messages, IRebusLoggerFactory rebusLoggerFactory, IAsyncTaskFactory asyncTaskFactory, TimeSpan replyMaxAge)
 {
     _messages = messages;
     _replyMaxAge = replyMaxAge;
     _log = rebusLoggerFactory.GetCurrentClassLogger();
     _cleanupTask = asyncTaskFactory.Create("CleanupAbandonedRepliesTask", CleanupAbandonedReplies);
 }
Exemplo n.º 2
0
 public ReplyHandlerStep(ConcurrentDictionary <string, TimedMessage> messages, IRebusLoggerFactory rebusLoggerFactory, IAsyncTaskFactory asyncTaskFactory, TimeSpan replyMaxAge)
 {
     _messages    = messages ?? throw new ArgumentNullException(nameof(messages));
     _log         = rebusLoggerFactory?.GetLogger <ReplyHandlerStep>() ?? throw new ArgumentNullException(nameof(rebusLoggerFactory));
     _cleanupTask = asyncTaskFactory?.Create("CleanupAbandonedRepliesTask", CleanupAbandonedReplies) ?? throw new ArgumentNullException(nameof(asyncTaskFactory));
     _replyMaxAge = replyMaxAge;
 }
Exemplo n.º 3
0
 /// <summary>
 /// Constructs the in-mem error tracker with the configured number of delivery attempts as the MAX
 /// </summary>
 public InMemErrorTracker(int maxDeliveryAttempts, IRebusLoggerFactory rebusLoggerFactory, IAsyncTaskFactory asyncTaskFactory)
 {
     if (rebusLoggerFactory == null) throw new ArgumentNullException(nameof(rebusLoggerFactory));
     if (asyncTaskFactory == null) throw new ArgumentNullException(nameof(asyncTaskFactory));
     _maxDeliveryAttempts = maxDeliveryAttempts;
     _log = rebusLoggerFactory.GetCurrentClassLogger();
     _cleanupOldTrackedErrorsTask = asyncTaskFactory.Create(BackgroundTaskName, CleanupOldTrackedErrors, intervalSeconds: 60);
 }
Exemplo n.º 4
0
        /// <summary>
        /// Constructs the step, using the specified <see cref="ITimeoutManager"/> to defer relevant messages
        /// and the specified <see cref="ITransport"/> to deliver messages when they're due.
        /// </summary>
        public HandleDeferredMessagesStep(ITimeoutManager timeoutManager, ITransport transport, Options options, IRebusLoggerFactory rebusLoggerFactory, IAsyncTaskFactory asyncTaskFactory)
        {
            _timeoutManager = timeoutManager;
            _transport = transport;
            _options = options;
            _log = rebusLoggerFactory.GetCurrentClassLogger();

            _dueMessagesSenderBackgroundTask = asyncTaskFactory.Create(DueMessagesSenderTaskName, TimerElapsed, intervalSeconds: 1);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Constructs the transport with the given <see cref="IDbConnectionProvider"/>, using the specified <paramref name="tableName"/> to send/receive messages,
        /// querying for messages with recipient = <paramref name="inputQueueName"/>
        /// </summary>
        public SqlServerTransport(IDbConnectionProvider connectionProvider, string tableName, string inputQueueName, IRebusLoggerFactory rebusLoggerFactory, IAsyncTaskFactory asyncTaskFactory)
        {
            _connectionProvider = connectionProvider;
            _tableName = tableName;
            _inputQueueName = inputQueueName;
            _log = rebusLoggerFactory.GetCurrentClassLogger();

            ExpiredMessagesCleanupInterval = DefaultExpiredMessagesCleanupInterval;

            _expiredMessagesCleanupTask = asyncTaskFactory.Create("ExpiredMessagesCleanup", PerformExpiredMessagesCleanupCycle, intervalSeconds: 60);
        }
Exemplo n.º 6
0
 /// <summary>
 /// Constructs the in-mem error tracker with the configured number of delivery attempts as the MAX
 /// </summary>
 public InMemErrorTracker(int maxDeliveryAttempts, IRebusLoggerFactory rebusLoggerFactory, IAsyncTaskFactory asyncTaskFactory)
 {
     if (rebusLoggerFactory == null)
     {
         throw new ArgumentNullException(nameof(rebusLoggerFactory));
     }
     if (asyncTaskFactory == null)
     {
         throw new ArgumentNullException(nameof(asyncTaskFactory));
     }
     _maxDeliveryAttempts = maxDeliveryAttempts;
     _log = rebusLoggerFactory.GetLogger <InMemErrorTracker>();
     _cleanupOldTrackedErrorsTask = asyncTaskFactory.Create(BackgroundTaskName, CleanupOldTrackedErrors, intervalSeconds: 60);
 }
        IAsyncTask CreateRenewalTaskForMessage(Message message, IAmazonSQS client)
        {
            return(_asyncTaskFactory.Create($"RenewPeekLock-{message.MessageId}",
                                            async() =>
            {
                _log.Info("Renewing peek lock for message with ID {messageId}", message.MessageId);

                var request = new ChangeMessageVisibilityRequest(_queueUrl, message.ReceiptHandle, (int)_peekLockDuration.TotalSeconds);

                await client.ChangeMessageVisibilityAsync(request);
            },
                                            intervalSeconds: (int)_peekLockRenewalInterval.TotalSeconds,
                                            prettyInsignificant: true));
        }
Exemplo n.º 8
0
 /// <summary>
 /// Constructs a MySql transport.
 /// </summary>
 public MySqlTransport(MySqlConnectionHelper connectionHelper, string tableName, string inputQueueName, IRebusLoggerFactory rebusLoggerFactory, IAsyncTaskFactory asyncTaskFactory, IRebusTime rebusTime)
 {
     if (rebusLoggerFactory == null)
     {
         throw new ArgumentNullException(nameof(rebusLoggerFactory));
     }
     _connectionHelper = connectionHelper;
     _tableName        = tableName;
     _inputQueueName   = inputQueueName;
     _asyncTaskFactory = asyncTaskFactory ?? throw new ArgumentNullException(nameof(asyncTaskFactory));
     _rebusTime        = rebusTime ?? throw new ArgumentNullException(nameof(rebusTime));
     ExpiredMessagesCleanupInterval = DefaultExpiredMessagesCleanupInterval;
     _expiredMessagesCleanupTask    = asyncTaskFactory.Create("ExpiredMessagesCleanup",
                                                              PerformExpiredMessagesCleanupCycle, intervalSeconds: 60);
     _log = rebusLoggerFactory.GetLogger <MySqlTransport>();
 }
Exemplo n.º 9
0
        public AutoScaler(ITransport transport, IRebusLoggerFactory rebusLoggerFactory, int maximumNumberOfWorkers, IAsyncTaskFactory asyncTaskFactory, Func <IBus> busFactory, int adjustmentIntervalSeconds)
        {
            if (rebusLoggerFactory == null)
            {
                throw new ArgumentNullException(nameof(rebusLoggerFactory));
            }
            if (asyncTaskFactory == null)
            {
                throw new ArgumentNullException(nameof(asyncTaskFactory));
            }

            _logger    = rebusLoggerFactory.GetLogger <AutoScaler>();
            _transport = transport ?? throw new ArgumentNullException(nameof(transport));
            _maximumNumberOfWorkers = maximumNumberOfWorkers;
            _busFactory             = busFactory ?? throw new ArgumentNullException(nameof(busFactory));
            _task = asyncTaskFactory.Create("AutoScale", Tick, intervalSeconds: adjustmentIntervalSeconds);
        }
        /// <summary>
        /// Constructs the transport, connecting to the service bus pointed to by the connection string.
        /// </summary>
        public AzureServiceBusTransport(string connectionString, string queueName, IRebusLoggerFactory rebusLoggerFactory, IAsyncTaskFactory asyncTaskFactory, INameFormatter nameFormatter, CancellationToken cancellationToken = default(CancellationToken), ITokenProvider tokenProvider = null)
        {
            if (rebusLoggerFactory == null)
            {
                throw new ArgumentNullException(nameof(rebusLoggerFactory));
            }
            if (asyncTaskFactory == null)
            {
                throw new ArgumentNullException(nameof(asyncTaskFactory));
            }

            _nameFormatter = nameFormatter;

            if (queueName != null)
            {
                // this never happens
                if (queueName.StartsWith(MagicSubscriptionPrefix))
                {
                    throw new ArgumentException($"Sorry, but the queue name '{queueName}' cannot be used because it conflicts with Rebus' internally used 'magic subscription prefix': '{MagicSubscriptionPrefix}'. ");
                }

                Address           = _nameFormatter.FormatQueueName(queueName);
                _subscriptionName = _nameFormatter.FormatSubscriptionName(queueName);
            }

            _connectionString  = connectionString ?? throw new ArgumentNullException(nameof(connectionString));
            _cancellationToken = cancellationToken;
            _log = rebusLoggerFactory.GetLogger <AzureServiceBusTransport>();

            if (tokenProvider != null)
            {
                var connectionStringBuilder = new ServiceBusConnectionStringBuilder(connectionString);
                _managementClient = new ManagementClient(connectionStringBuilder, tokenProvider);
                _endpoint         = connectionStringBuilder.Endpoint;
                _transportType    = connectionStringBuilder.TransportType;
            }
            else
            {
                _managementClient = new ManagementClient(connectionString);
            }

            _tokenProvider = tokenProvider;

            _messageLockRenewalTask = asyncTaskFactory.Create("Peek Lock Renewal", RenewPeekLocks, prettyInsignificant: true, intervalSeconds: 10);
        }
Exemplo n.º 11
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="connectionProvider">A <see cref="IDbConnection"/> to obtain a database connection</param>
        /// <param name="inputQueueName">Name of the queue this transport is servicing</param>
        /// <param name="rebusLoggerFactory">A <seealso cref="IRebusLoggerFactory"/> for building loggers</param>
        /// <param name="asyncTaskFactory">A <seealso cref="IAsyncTaskFactory"/> for creating periodic tasks</param>
        /// <param name="rebusTime">A <seealso cref="IRebusTime"/> to provide the current time</param>
        /// <param name="options">Additional options</param>
        public MySqlTransport(
            IDbConnectionProvider connectionProvider,
            string inputQueueName,
            IRebusLoggerFactory rebusLoggerFactory,
            IAsyncTaskFactory asyncTaskFactory,
            IRebusTime rebusTime,
            MySqlTransportOptions options)
        {
            if (rebusLoggerFactory == null)
            {
                throw new ArgumentNullException(nameof(rebusLoggerFactory));
            }
            if (asyncTaskFactory == null)
            {
                throw new ArgumentNullException(nameof(asyncTaskFactory));
            }

            _rebusTime          = rebusTime ?? throw new ArgumentNullException(nameof(rebusTime));
            _connectionProvider = connectionProvider ?? throw new ArgumentNullException(nameof(connectionProvider));
            _receiveTableName   = inputQueueName != null?TableName.Parse(inputQueueName) : null;

            _log = rebusLoggerFactory.GetLogger <MySqlTransport>();

            var cleanupInterval = options.ExpiredMessagesCleanupInterval ?? DefaultExpiredMessagesCleanupInterval;
            var intervalSeconds = (int)cleanupInterval.TotalSeconds;

            _expiredMessagesCleanupTask = asyncTaskFactory.Create("ExpiredMessagesCleanup", PerformExpiredMessagesCleanupCycle, intervalSeconds: intervalSeconds);
            _autoDeleteQueue            = options.AutoDeleteQueue;
            _leasedByFactory            = options.LeasedByFactory ?? (() => Environment.MachineName);
            _leaseInterval          = options.LeaseInterval ?? DefaultLeaseTime;
            _leaseTolerance         = options.LeaseInterval ?? DefaultLeaseTolerance;
            _ensureTablesAreCreated = options.EnsureTablesAreCreated;

            var automaticLeaseRenewalInterval = options.LeaseAutoRenewInterval;

            if (!automaticLeaseRenewalInterval.HasValue)
            {
                _automaticLeaseRenewal = false;
            }
            else
            {
                _automaticLeaseRenewal         = true;
                _automaticLeaseRenewalInterval = automaticLeaseRenewalInterval.Value;
            }
        }
Exemplo n.º 12
0
        /// <summary>
        /// Constructs the step, using the specified <see cref="ITimeoutManager"/> to defer relevant messages
        /// and the specified <see cref="ITransport"/> to deliver messages when they're due.
        /// </summary>
        public HandleDeferredMessagesStep(ITimeoutManager timeoutManager, ITransport transport, Options options, IRebusLoggerFactory rebusLoggerFactory, IAsyncTaskFactory asyncTaskFactory)
        {
            if (timeoutManager == null) throw new ArgumentNullException(nameof(timeoutManager));
            if (transport == null) throw new ArgumentNullException(nameof(transport));
            if (options == null) throw new ArgumentNullException(nameof(options));
            if (rebusLoggerFactory == null) throw new ArgumentNullException(nameof(rebusLoggerFactory));
            if (asyncTaskFactory == null) throw new ArgumentNullException(nameof(asyncTaskFactory));

            _timeoutManager = timeoutManager;
            _transport = transport;
            _options = options;
            _log = rebusLoggerFactory.GetCurrentClassLogger();

            var dueTimeoutsPollIntervalSeconds = (int)options.DueTimeoutsPollInterval.TotalSeconds;
            var intervalToUse = dueTimeoutsPollIntervalSeconds >= 1 ? dueTimeoutsPollIntervalSeconds : 1;

            _dueMessagesSenderBackgroundTask = asyncTaskFactory.Create(DueMessagesSenderTaskName, TimerElapsed, intervalSeconds: intervalToUse);
        }
Exemplo n.º 13
0
        /// <summary>
        /// Constructs the step, using the specified <see cref="ITimeoutManager"/> to defer relevant messages
        /// and the specified <see cref="ITransport"/> to deliver messages when they're due.
        /// </summary>
        public HandleDeferredMessagesStep(ITimeoutManager timeoutManager, ITransport transport, Options options, IRebusLoggerFactory rebusLoggerFactory, IAsyncTaskFactory asyncTaskFactory)
        {
            if (rebusLoggerFactory == null)
            {
                throw new ArgumentNullException(nameof(rebusLoggerFactory));
            }
            if (asyncTaskFactory == null)
            {
                throw new ArgumentNullException(nameof(asyncTaskFactory));
            }

            _timeoutManager = timeoutManager ?? throw new ArgumentNullException(nameof(timeoutManager));
            _transport      = transport ?? throw new ArgumentNullException(nameof(transport));
            _options        = options ?? throw new ArgumentNullException(nameof(options));

            _log = rebusLoggerFactory.GetLogger <HandleDeferredMessagesStep>();

            _dueMessagesSenderBackgroundTask = asyncTaskFactory.Create(DueMessagesSenderTaskName, TimerElapsed, interval: options.DueTimeoutsPollInterval);
        }
Exemplo n.º 14
0
        /// <summary>
        /// Constructs the transport with the given <see cref="IDbConnectionProvider"/>
        /// </summary>
        public SqlServerTransport(IDbConnectionProvider connectionProvider, string inputQueueName, IRebusLoggerFactory rebusLoggerFactory, IAsyncTaskFactory asyncTaskFactory)
        {
            if (rebusLoggerFactory == null)
            {
                throw new ArgumentNullException(nameof(rebusLoggerFactory));
            }
            if (asyncTaskFactory == null)
            {
                throw new ArgumentNullException(nameof(asyncTaskFactory));
            }

            ConnectionProvider = connectionProvider ?? throw new ArgumentNullException(nameof(connectionProvider));
            ReceiveTableName   = inputQueueName != null?TableName.Parse(inputQueueName) : null;

            _log = rebusLoggerFactory.GetLogger <SqlServerTransport>();

            ExpiredMessagesCleanupInterval = DefaultExpiredMessagesCleanupInterval;

            _expiredMessagesCleanupTask = asyncTaskFactory.Create("ExpiredMessagesCleanup", PerformExpiredMessagesCleanupCycle, intervalSeconds: 60);
        }
        IDisposable GetRenewalTaskOrFakeDisposable(string messageId, BrokeredMessage brokeredMessage, TimeSpan lockRenewalInterval)
        {
            if (AutomaticallyRenewPeekLock)
            {
                var renewalTask = _asyncTaskFactory.Create($"RenewPeekLock-{messageId}",
                                                           async() =>
                {
                    _log.Info("Renewing peek lock for message with ID {0}", messageId);

                    await brokeredMessage.RenewLockAsync();
                },
                                                           intervalSeconds: (int)lockRenewalInterval.TotalSeconds,
                                                           prettyInsignificant: true);

                renewalTask.Start();

                return(renewalTask);
            }

            return(new FakeDisposable());
        }
Exemplo n.º 16
0
        /// <summary>
        /// Constructs the in-mem error tracker with the configured number of delivery attempts as the MAX
        /// </summary>
        public InMemErrorTracker(SimpleRetryStrategySettings simpleRetryStrategySettings, IRebusLoggerFactory rebusLoggerFactory, IAsyncTaskFactory asyncTaskFactory, ITransport transport)
        {
            if (rebusLoggerFactory == null)
            {
                throw new ArgumentNullException(nameof(rebusLoggerFactory));
            }
            if (asyncTaskFactory == null)
            {
                throw new ArgumentNullException(nameof(asyncTaskFactory));
            }

            _simpleRetryStrategySettings = simpleRetryStrategySettings ?? throw new ArgumentNullException(nameof(simpleRetryStrategySettings));
            _transport = transport ?? throw new ArgumentNullException(nameof(transport));

            _log = rebusLoggerFactory.GetLogger <InMemErrorTracker>();

            _cleanupOldTrackedErrorsTask = asyncTaskFactory.Create(
                BackgroundTaskName,
                CleanupOldTrackedErrors,
                intervalSeconds: 10
                );
        }
        /// <summary>
        /// Constructs the transport with the given <see cref="IDbConnectionProvider"/>
        /// </summary>
        public MySqlTransport(IDbConnectionProvider connectionProvider, string inputQueueName, IRebusLoggerFactory rebusLoggerFactory, IAsyncTaskFactory asyncTaskFactory, IRebusTime rebusTime, MySqlTransportOptions options)
        {
            if (rebusLoggerFactory == null)
            {
                throw new ArgumentNullException(nameof(rebusLoggerFactory));
            }
            if (asyncTaskFactory == null)
            {
                throw new ArgumentNullException(nameof(asyncTaskFactory));
            }

            _rebusTime          = rebusTime ?? throw new ArgumentNullException(nameof(rebusTime));
            _connectionProvider = connectionProvider ?? throw new ArgumentNullException(nameof(connectionProvider));
            _receiveTableName   = inputQueueName != null?TableName.Parse(inputQueueName) : null;

            _log = rebusLoggerFactory.GetLogger <MySqlTransport>();

            var cleanupInterval = options.ExpiredMessagesCleanupInterval ?? DefaultExpiredMessagesCleanupInterval;
            var intervalSeconds = (int)cleanupInterval.TotalSeconds;

            _expiredMessagesCleanupTask = asyncTaskFactory.Create("ExpiredMessagesCleanup", PerformExpiredMessagesCleanupCycle, intervalSeconds: intervalSeconds);
            _autoDeleteQueue            = options.AutoDeleteQueue;
        }
        /// <summary>
        /// Receives the next message from the input queue. Returns null if no message was available
        /// </summary>
        public async Task <TransportMessage> Receive(ITransactionContext context, CancellationToken cancellationToken)
        {
            var receivedMessage = await ReceiveInternal().ConfigureAwait(false);

            if (receivedMessage == null)
            {
                return(null);
            }

            var message         = receivedMessage.Message;
            var messageReceiver = receivedMessage.MessageReceiver;

            if (!message.SystemProperties.IsLockTokenSet)
            {
                throw new RebusApplicationException($"OMG that's weird - message with ID {message.MessageId} does not have a lock token!");
            }

            var lockToken = message.SystemProperties.LockToken;
            var messageId = message.MessageId;

            if (AutomaticallyRenewPeekLock && !_prefetchingEnabled)
            {
                var now                 = DateTime.UtcNow;
                var leaseDuration       = message.SystemProperties.LockedUntilUtc - now;
                var lockRenewalInterval = TimeSpan.FromMinutes(0.5 * leaseDuration.TotalMinutes);

                var cancellationTokenSource = new CancellationTokenSource();
                var renewalTask             = _asyncTaskFactory
                                              .Create(description: $"RenewPeekLock-{messageId}",
                                                      action: () => RenewPeekLock(messageReceiver, messageId, lockToken, cancellationTokenSource),
                                                      intervalSeconds: (int)lockRenewalInterval.TotalSeconds,
                                                      prettyInsignificant: true
                                                      );

                // be sure to stop the renewal task regardless of whether we're committing or aborting
                context.OnCommitted(async() => renewalTask.Dispose());
                context.OnAborted(() => renewalTask.Dispose());
                context.OnDisposed(() =>
                {
                    renewalTask.Dispose();
                    cancellationTokenSource.Dispose();
                });

                cancellationTokenSource.Token.Register(renewalTask.Dispose);

                renewalTask.Start();
            }

            context.OnCompleted(async() =>
            {
                try
                {
                    await messageReceiver.CompleteAsync(lockToken).ConfigureAwait(false);
                }
                catch (Exception exception)
                {
                    throw new RebusApplicationException(exception,
                                                        $"Could not complete message with ID {message.MessageId} and lock token {lockToken}");
                }
            });

            context.OnAborted(() =>
            {
                try
                {
                    AsyncHelpers.RunSync(async() => await messageReceiver.AbandonAsync(lockToken).ConfigureAwait(false));
                }
                catch (Exception exception)
                {
                    throw new RebusApplicationException(exception,
                                                        $"Could not abandon message with ID {message.MessageId} and lock token {lockToken}");
                }
            });

            var userProperties = message.UserProperties;
            var headers        = userProperties.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.ToString());
            var body           = message.Body;

            return(new TransportMessage(headers, body));
        }
Exemplo n.º 19
0
 /// <summary>
 /// Constructs the in-mem error tracker with the configured number of delivery attempts as the MAX
 /// </summary>
 public InMemErrorTracker(int maxDeliveryAttempts, IRebusLoggerFactory rebusLoggerFactory, IAsyncTaskFactory asyncTaskFactory)
 {
     _maxDeliveryAttempts = maxDeliveryAttempts;
     _log = rebusLoggerFactory.GetCurrentClassLogger();
     _cleanupOldTrackedErrorsTask = asyncTaskFactory.Create(BackgroundTaskName, CleanupOldTrackedErrors, intervalSeconds: 60);
 }
Exemplo n.º 20
0
        /// <summary>
        /// Receives the next message from the input queue. Returns null if no message was available
        /// </summary>
        public async Task <TransportMessage> Receive(ITransactionContext context, CancellationToken cancellationToken)
        {
            var receivedMessage = await ReceiveInternal().ConfigureAwait(false);

            if (receivedMessage == null)
            {
                return(null);
            }

            var message         = receivedMessage.Message;
            var messageReceiver = receivedMessage.MessageReceiver;

            if (!message.SystemProperties.IsLockTokenSet)
            {
                throw new RebusApplicationException($"OMG that's weird - message with ID {message.MessageId} does not have a lock token!");
            }

            var lockToken = message.SystemProperties.LockToken;
            var messageId = message.MessageId;

            CancellationTokenSource cancellationTokenSource = null;
            IAsyncTask renewalTask = null;

            if (AutomaticallyRenewPeekLock && !_prefetchingEnabled)
            {
                var now                 = DateTime.UtcNow;
                var leaseDuration       = message.SystemProperties.LockedUntilUtc - now;
                var lockRenewalInterval = TimeSpan.FromMinutes(0.5 * leaseDuration.TotalMinutes);

                cancellationTokenSource = new CancellationTokenSource();
                renewalTask             = _asyncTaskFactory
                                          .Create(description: $"RenewPeekLock-{messageId}",
                                                  action: () => RenewPeekLock(messageReceiver, messageId, lockToken, cancellationTokenSource),
                                                  intervalSeconds: (int)lockRenewalInterval.TotalSeconds,
                                                  prettyInsignificant: true
                                                  );

                cancellationTokenSource.Token.Register(renewalTask.Dispose);

                renewalTask.Start();
            }

            context.OnCompleted(async ctx =>
            {
                try
                {
                    await messageReceiver.CompleteAsync(lockToken).ConfigureAwait(false);
                }
                catch (Exception exception)
                {
                    throw new RebusApplicationException(exception,
                                                        $"Could not complete message with ID {message.MessageId} and lock token {lockToken}");
                }

                // Dispose the renewal task after the message has been removed.
                // Note that we could get a MessageLockLostException and log an error in RenewPeekLock in the off chance that renewal runs between CompleteAsync and Dispose here,
                // but that's better than disposing the renewal first and potentially loosing the lock before calling complete.
                renewalTask?.Dispose();
            });

            context.OnAborted(async ctx =>
            {
                // Dispose the renewal before abandoning the message, otherwise renewal could grab the lock again.
                renewalTask?.Dispose();

                try
                {
                    await messageReceiver.AbandonAsync(lockToken).ConfigureAwait(false);
                }
                catch (Exception exception)
                {
                    throw new RebusApplicationException(exception,
                                                        $"Could not abandon message with ID {message.MessageId} and lock token {lockToken}");
                }
            });

            context.OnDisposed(ctx =>
            {
                renewalTask?.Dispose();
                cancellationTokenSource?.Dispose();
            });

            var userProperties = message.UserProperties;
            var headers        = userProperties.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.ToString());
            var body           = message.Body;

            return(new TransportMessage(headers, body));
        }
Exemplo n.º 21
0
 /// <summary>
 /// Constructs the in-mem error tracker with the configured number of delivery attempts as the MAX
 /// </summary>
 public InMemErrorTracker(int maxDeliveryAttempts, IRebusLoggerFactory rebusLoggerFactory, IAsyncTaskFactory asyncTaskFactory)
 {
     _maxDeliveryAttempts = maxDeliveryAttempts;
     _log = rebusLoggerFactory.GetCurrentClassLogger();
     _cleanupOldTrackedErrorsTask = asyncTaskFactory.Create(BackgroundTaskName, CleanupOldTrackedErrors, intervalSeconds: 60);
 }