public Task Init(Func <MessageContext, Task> onMessage, Func <ErrorContext, Task <ErrorHandleResult> > onError, CriticalError criticalError, PushSettings settings) { peekCircuitBreaker = new RepeatedFailuresOverTimeCircuitBreaker("MsmqPeek", TimeSpan.FromSeconds(30), ex => criticalError.Raise("Failed to peek " + settings.InputQueue, ex)); receiveCircuitBreaker = new RepeatedFailuresOverTimeCircuitBreaker("MsmqReceive", TimeSpan.FromSeconds(30), ex => criticalError.Raise("Failed to receive from " + settings.InputQueue, ex)); var inputAddress = MsmqAddress.Parse(settings.InputQueue); var errorAddress = MsmqAddress.Parse(settings.ErrorQueue); if (!string.Equals(inputAddress.Machine, RuntimeEnvironment.MachineName, StringComparison.OrdinalIgnoreCase)) { throw new Exception($"MSMQ Dequeuing can only run against the local machine. Invalid inputQueue name '{settings.InputQueue}'."); } inputQueue = new MessageQueue(inputAddress.FullPath, false, true, QueueAccessMode.Receive); errorQueue = new MessageQueue(errorAddress.FullPath, false, true, QueueAccessMode.Send); if (settings.RequiredTransactionMode != TransportTransactionMode.None && !QueueIsTransactional()) { throw new ArgumentException($"Queue must be transactional if you configure the endpoint to be transactional ({settings.InputQueue})."); } inputQueue.MessageReadPropertyFilter = DefaultReadPropertyFilter; if (settings.PurgeOnStartup) { inputQueue.Purge(); } receiveStrategy = receiveStrategyFactory(settings.RequiredTransactionMode); receiveStrategy.Init(inputQueue, errorQueue, onMessage, onError, criticalError); return(TaskEx.CompletedTask); }
public Task StartReceive(CancellationToken cancellationToken = default) { MessageQueue.ClearConnectionCache(); messagePumpCancellationTokenSource = new CancellationTokenSource(); messageProcessingCancellationTokenSource = new CancellationTokenSource(); peekCircuitBreaker = new RepeatedFailuresOverTimeCircuitBreaker("MsmqPeek", TimeSpan.FromSeconds(30), ex => criticalErrorAction("Failed to peek " + receiveSettings.ReceiveAddress, ex, messageProcessingCancellationTokenSource.Token)); receiveCircuitBreaker = new RepeatedFailuresOverTimeCircuitBreaker("MsmqReceive", TimeSpan.FromSeconds(30), ex => criticalErrorAction("Failed to receive from " + receiveSettings.ReceiveAddress, ex, messageProcessingCancellationTokenSource.Token)); // LongRunning is useless combined with async/await messagePumpTask = Task.Run(() => PumpMessages(), cancellationToken); return(Task.CompletedTask); }
public Task StartReceive(CancellationToken cancellationToken = default) { MessageQueue.ClearConnectionCache(); messagePumpCancellationTokenSource = new CancellationTokenSource(); messageProcessingCancellationTokenSource = new CancellationTokenSource(); peekCircuitBreaker = new RepeatedFailuresOverTimeCircuitBreaker("MsmqPeek", TimeSpan.FromSeconds(30), ex => criticalErrorAction("Failed to peek " + receiveSettings.ReceiveAddress, ex, messageProcessingCancellationTokenSource.Token)); receiveCircuitBreaker = new RepeatedFailuresOverTimeCircuitBreaker("MsmqReceive", TimeSpan.FromSeconds(30), ex => criticalErrorAction("Failed to receive from " + receiveSettings.ReceiveAddress, ex, messageProcessingCancellationTokenSource.Token)); // Task.Run() so the call returns immediately instead of waiting for the first await or return down the call stack // LongRunning is useless combined with async/await messagePumpTask = Task.Run(() => PumpMessagesAndSwallowExceptions(messagePumpCancellationTokenSource.Token), CancellationToken.None); return(Task.CompletedTask); }