protected override async Task <MessageProcessingResult> DispatchMessage(TransportMessage message, long taskId, CancellationToken token, ITransactionContext context) { if (context == null) { throw new ArgumentNullException(nameof(context), "ITransactionContext context == null"); } var stepContext = new IncomingStepContext(message, context); await _pipelineInvoker.Invoke(stepContext); return(new MessageProcessingResult { isRollBack = false }); }
async Task ProcessMessage(TransactionContext context, TransportMessage transportMessage) { try { AmbientTransactionContext.SetCurrent(context); var stepContext = new IncomingStepContext(transportMessage, context); await _pipelineInvoker.Invoke(stepContext); try { await context.Complete(); } catch (Exception exception) { _log.Error(exception, "An error occurred when attempting to complete the transaction context"); } } catch (OperationCanceledException exception) { context.Abort(); _log.Error(exception, "Worker was aborted while handling message {messageLabel}", transportMessage.GetMessageLabel()); } catch (Exception exception) { context.Abort(); _log.Error(exception, "Unhandled exception while handling message {messageLabel}", transportMessage.GetMessageLabel()); } finally { AmbientTransactionContext.SetCurrent(null); } }
async void TryReceiveNewMessage() { using (var operation = _parallelOperationsManager.TryBegin()) { // if we didn't get to do our thing, pause the thread a very short while to avoid thrashing too much if (!operation.CanContinue()) { Thread.Sleep(10); return; } using (var transactionContext = new DefaultTransactionContext()) { AmbientTransactionContext.Current = transactionContext; try { var message = await TryReceiveTransportMessage(transactionContext); if (message == null) { // no message: finish the tx and wait.... await transactionContext.Complete(); await _backoffStrategy.Wait(); return; } // we got a message, so we reset the backoff strategy _backoffStrategy.Reset(); var context = new IncomingStepContext(message, transactionContext); var stagedReceiveSteps = _pipeline.ReceivePipeline(); await _pipelineInvoker.Invoke(context, stagedReceiveSteps); try { await transactionContext.Complete(); } catch (Exception exception) { _log.Error(exception, "An error occurred when attempting to complete the transaction context"); } } catch (Exception exception) { // we should not end up here unless something is off.... _log.Error(exception, "Unhandled exception in thread worker - the pipeline didn't handle its own errors (this is bad)"); Thread.Sleep(100); } finally { AmbientTransactionContext.Current = null; } } } }
async void TryProcessMessage() { using (var op = _parallelOperationsManager.TryBegin()) { if (!op.CanContinue()) { Thread.Sleep(10); return; } using (var transactionContext = new DefaultTransactionContext()) { AmbientTransactionContext.Current = transactionContext; try { var message = await _transport.Receive(transactionContext); if (message == null) { // finish the tx and wait.... await transactionContext.Complete(); await _backoffHelper.Wait(); return; } _backoffHelper.Reset(); var context = new IncomingStepContext(message, transactionContext); transactionContext.Items[StepContext.StepContextKey] = context; var stagedReceiveSteps = _pipeline.ReceivePipeline(); await _pipelineInvoker.Invoke(context, stagedReceiveSteps); await transactionContext.Complete(); } catch (Exception exception) { _log.Error(exception, "Unhandled exception in thread worker"); } finally { AmbientTransactionContext.Current = null; } } } }
async Task ProcessMessage(TransactionContext context, TransportMessage transportMessage) { try { context.Items["OwningBus"] = _owningBus; AmbientTransactionContext.SetCurrent(context); var incomingSteps = _pipeline.ReceivePipeline(); var stepContext = new IncomingStepContext(transportMessage, context); await _pipelineInvoker.Invoke(stepContext, incomingSteps); try { await context.Complete(); } catch (Exception exception) { _log.Error(exception, "An error occurred when attempting to complete the transaction context"); } } catch (ThreadAbortException exception) { context.Abort(); _log.Error(exception, $"Worker was killed while handling message {transportMessage.GetMessageLabel()}"); } catch (Exception exception) { context.Abort(); _log.Error(exception, $"Unhandled exception while handling message {transportMessage.GetMessageLabel()}"); } finally { AmbientTransactionContext.SetCurrent(null); } }
async Task SendUsingTransactionContext(IEnumerable <string> destinationAddresses, Message logicalMessage, ITransactionContext transactionContext) { var context = new OutgoingStepContext(logicalMessage, transactionContext, new DestinationAddresses(destinationAddresses)); await _pipelineInvoker.Invoke(context, _pipeline.SendPipeline()); }
async void TryReceiveNewMessage() { using (var operation = _parallelOperationsManager.TryBegin()) { // if we didn't get to do our thing, let the OS decide what to do next.... we don't hog the processor if (!operation.CanContinue()) { Thread.Yield(); return; } using (var transactionContext = new DefaultTransactionContext()) { transactionContext.Items["CancellationToken"] = _cancellationTokenSource.Token; transactionContext.Items["OwningBus"] = _owningBus; AmbientTransactionContext.Current = transactionContext; try { var result = await TryReceiveTransportMessage(transactionContext, _cancellationTokenSource.Token); if (result.Exception != null) { if (result.Exception is TaskCanceledException || result.Exception is OperationCanceledException) { // this is normal - we're being shut down so we just return quickly transactionContext.Dispose(); return; } _log.Warn("An error occurred when attempting to receive transport message: {0}", result.Exception); // error: finish the tx and wait.... transactionContext.Dispose(); await _backoffStrategy.WaitError(); return; } var message = result.TransportMessage; if (message == null) { // no message: finish the tx and wait.... await transactionContext.Complete(); transactionContext.Dispose(); await _backoffStrategy.Wait(); return; } // we got a message, so we reset the backoff strategy _backoffStrategy.Reset(); var context = new IncomingStepContext(message, transactionContext); var stagedReceiveSteps = _pipeline.ReceivePipeline(); await _pipelineInvoker.Invoke(context, stagedReceiveSteps); try { await transactionContext.Complete(); } catch (Exception exception) { _log.Error(exception, "An error occurred when attempting to complete the transaction context"); } } catch (Exception exception) { // we should not end up here unless something is off.... _log.Error(exception, "Unhandled exception in thread worker - the pipeline didn't handle its own errors (this is bad)"); Thread.Sleep(100); } finally { AmbientTransactionContext.Current = null; } } } }