/// <summary>
        /// Invoked when an error occurs while processing a message.
        /// </summary>
        /// <param name="handlingContext">Error handling context.</param>
        /// <param name="dispatcher">Dispatcher.</param>
        public async Task <ErrorHandleResult> OnError(IErrorHandlingPolicyContext handlingContext, IDispatchMessages dispatcher)
        {
            var message = handlingContext.Error.Message;

            if (handlingContext.Error.ImmediateProcessingFailures < immediateRetries)
            {
                return(ErrorHandleResult.RetryRequired);
            }
            string delayedRetryHeader;

            if (message.Headers.TryGetValue("NServiceBus.Raw.DelayedRetries.Attempt", out delayedRetryHeader))
            {
                var attempt = int.Parse(delayedRetryHeader);
                if (attempt >= delayedRetries)
                {
                    await handlingContext.MoveToErrorQueue(errorQueue).ConfigureAwait(false);

                    return(ErrorHandleResult.Handled);
                }
            }

            message.Headers["NServiceBus.Raw.DelayedRetries.Due"]     = (DateTime.UtcNow + delay).ToString("O");
            message.Headers["NServiceBus.Raw.DelayedRetries.RetryTo"] = handlingContext.FailedQueue;
            var delayedMessage = new OutgoingMessage(message.MessageId, message.Headers, message.Body);
            var operation      = new TransportOperation(delayedMessage, new UnicastAddressTag(delayQueue));
            await dispatcher.Dispatch(new TransportOperations(operation), handlingContext.Error.TransportTransaction, new ContextBag())
            .ConfigureAwait(false);

            return(ErrorHandleResult.Handled);
        }
예제 #2
0
        async Task OnMessage(MessageContext context, IDispatchMessages dispatcher, Task <bool> barrier, ICollection <string> ownCatalogs)
        {
            //Ensure all endpoinst are created.
            await barrier.ConfigureAwait(false);

            string destination;

            if (!context.Headers.TryGetValue("NServiceBus.SqlServer.Destination", out destination))
            {
                throw new Exception("No destination header present.");
            }
            context.Headers.Remove("NServiceBus.SqlServer.Destination");

            var address = QueueAddress.Parse(destination);

            var outgoingMessage = new OutgoingMessage(context.MessageId, context.Headers, context.Body);
            var operation       = new TransportOperation(outgoingMessage, new UnicastAddressTag(destination));
            var operations      = new TransportOperations(operation);

            if (ownCatalogs.Contains(address.Catalog)) //Forward to the same instance on the receiving connection/transaction
            {
                await dispatcher.Dispatch(operations, context.TransportTransaction, context.Context).ConfigureAwait(false);
            }
            else //Forward to different instance
            {
                IRawEndpointInstance forwarder;
                if (!endpointsByCatalog.TryGetValue(address.Catalog, out forwarder))
                {
                    throw new Exception($"Destination catalog {address.Catalog} is not configured.");
                }
                await forwarder.SendRaw(operations, new TransportTransaction(), new ContextBag()).ConfigureAwait(false);
            }
        }
        public static Task Send(this IDispatchMessages endpoint, Message message, Guid?runId = null)
        {
            runId ??= Guid.NewGuid();

            var headers = new Dictionary <string, string>
            {
                { "Message.Id", message.Id.ToString() },
                { "Message.RunId", runId.ToString() }
            };

            var body = Serializer.Serialize(message, headers);

            var request = new OutgoingMessage(
                messageId: Guid.NewGuid().ToString(),
                headers: headers,
                body: body);

            var operation = new TransportOperation(
                request,
                new UnicastAddressTag(EndpointBuilder.EndpointName));

            return(endpoint.Dispatch(
                       outgoingMessages: new TransportOperations(operation),
                       transaction: new TransportTransaction(),
                       context: new ContextBag()));
        }
예제 #4
0
        public async Task Publish(MessageContext context, IDispatchMessages dispatcher)
        {
            var messageTypes = Get(context, Headers.EnclosedMessageTypes, "Publish")
                               .Split(EnclosedMessageTypeSeparator)
                               .Select(t => new MessageType(t));

            var subscribers = await store.GetSubscriberAddressesForMessage(messageTypes, context.Extensions);

            var logicalSubscribers = subscribers.GroupBy(s => s.Endpoint, s => s.TransportAddress);

            var destinations = logicalSubscribers.Select(subscriber =>
                                                         distributor.SelectDestination(subscriber.Key, subscriber.ToArray(), context));

            var operations = destinations.Select(destination => new TransportOperation(
                                                     new OutgoingMessage(context.MessageId, context.Headers, context.Body),
                                                     new UnicastAddressTag(destination))).ToArray();

            if (!operations.Any())
            {
                // Log that we didn't dispatch anything
                return;
            }

            await dispatcher.Dispatch(new TransportOperations(operations), context.TransportTransaction, context.Extensions);
        }
예제 #5
0
        protected override async Task Publish(string messageId, Guid attemptId,
                                              IEnumerable <OutgoingMessageRecord> committedSideEffects,
                                              IEnumerable <OutgoingMessageRecord> abortedSideEffects)
        {
            var operations = committedSideEffects.Select(r => r.ToTransportOperation()).ToArray();

            if (log.IsDebugEnabled)
            {
                log.Debug($"Dispatching messages {string.Join(",", operations.Select(o => o.Message.MessageId))} generated by attempt {attemptId} of transaction {messageId}.");
            }

            await dispatcher.Dispatch(new TransportOperations(operations), new TransportTransaction(), new ContextBag())
            .ConfigureAwait(false);

            var abortedIds = abortedSideEffects.Select(r => r.Id).ToArray();

            if (log.IsDebugEnabled)
            {
                log.Debug($"Removing tokens for aborted message send attempts {string.Join(", ", abortedIds)}");
            }
            await messageStore.EnsureDeleted(abortedIds)
            .ConfigureAwait(false);

            if (log.IsDebugEnabled)
            {
                log.Debug($"Removing token for successfully processed message {messageId}.");
            }
            await messageStore.Delete(messageId).ConfigureAwait(false);
        }
        public async Task <ErrorHandleResult> OnError(IErrorHandlingPolicyContext handlingContext, IDispatchMessages dispatcher)
        {
            if (handlingContext.Error.ImmediateProcessingFailures < immediateRetries)
            {
                return(ErrorHandleResult.RetryRequired);
            }

            if (handlingContext.Error.DelayedDeliveriesPerformed >= delayedRetries)
            {
                //More than five times this message triggered throttled mode -> poison
                return(await poisonMessageHandling(handlingContext, dispatcher).ConfigureAwait(false));
            }

            //Move to back of the queue.
            var incomingMessage = handlingContext.Error.Message;
            var message         = new OutgoingMessage(incomingMessage.MessageId, incomingMessage.Headers, incomingMessage.Body);
            var operation       = new TransportOperation(message, new UnicastAddressTag(inputQueue));

            //Only increment the delayed retries count if CB was not armed. That means that at least one message was
            //successfully forwarded in between previous failure of this message and this failure.
            //This prevents prematurely exhausting delayed retries attempts without triggering the throttled mode
            if (!circuitBreaker.IsArmed)
            {
                var newDelayedRetriesHeaderValue = handlingContext.Error.DelayedDeliveriesPerformed + 1;
                incomingMessage.Headers[Headers.DelayedRetries] = newDelayedRetriesHeaderValue.ToString();
            }
            await dispatcher.Dispatch(new TransportOperations(operation), handlingContext.Error.TransportTransaction, new ContextBag())
            .ConfigureAwait(false);

            //Notify the circuit breaker
            await circuitBreaker.Failure(handlingContext.Error.Exception).ConfigureAwait(false);

            return(ErrorHandleResult.Handled);
        }
예제 #7
0
            static async Task Send(IDispatchMessages dispatchMessages, int messageNumber)
            {
                try
                {
                    if (!concurrencyLimiter.Wait(0))
                    {
                        await concurrencyLimiter.WaitAsync();
                    }
                    var headers = new Dictionary <string, string>(reusedHeaders);

                    var messageId = Guid.NewGuid().ToString();
                    headers[Headers.MessageId]      = messageId;
                    headers[Headers.CorrelationId]  = messageId;
                    headers[Headers.ConversationId] = Guid.NewGuid().ToString();
                    headers[Headers.MessageIntent]  = "Send";
                    headers[Headers.TimeSent]       = DateTimeExtensions.ToWireFormattedString(DateTime.UtcNow);

                    ExceptionHeaderHelper.SetExceptionHeaders(headers, exceptions[messageNumber % 3]);

                    var message   = new OutgoingMessage(messageId, headers, content);
                    var operation = new TransportOperation(message, new UnicastAddressTag("error"));
                    await dispatchMessages.Dispatch(new TransportOperations(operation), transportTransaction, contextBag);

                    // no overwhelm with too much output
                    if (messageNumber % 1000 == 0)
                    {
                        await Console.Error.WriteLineAsync($"|{messageNumber}|");
                    }
                }
                finally
                {
                    concurrencyLimiter.Release();
                }
            }
예제 #8
0
        public virtual async Task HandleMessage(MessageContext message, IDispatchMessages sender)
        {
            var body            = new byte[0];
            var outgoingHeaders = new Dictionary <string, string>(message.Headers);

            outgoingHeaders.Remove("ServiceControl.Retry.StagingId");

            var messageId = message.MessageId;

            Log.DebugFormat("{0}: Retrieving message body", messageId);

            if (outgoingHeaders.TryGetValue("ServiceControl.Retry.Attempt.MessageId", out var attemptMessageId))
            {
                var result = await bodyStorage.TryFetch(attemptMessageId)
                             .ConfigureAwait(false);

                if (result.HasResult)
                {
                    using (result.Stream)
                    {
                        body = ReadFully(result.Stream);
                    }

                    Log.DebugFormat("{0}: Body size: {1} bytes", messageId, body.LongLength);
                }
                else
                {
                    Log.WarnFormat("{0}: Message Body not found for attempt Id {1}", messageId, attemptMessageId);
                }

                outgoingHeaders.Remove("ServiceControl.Retry.Attempt.MessageId");
            }
            else
            {
                Log.WarnFormat("{0}: Can't find message body. Missing header ServiceControl.Retry.Attempt.MessageId", messageId);
            }

            var outgoingMessage = new OutgoingMessage(messageId, outgoingHeaders, body);

            var destination = outgoingHeaders["ServiceControl.TargetEndpointAddress"];

            Log.DebugFormat("{0}: Forwarding message to {1}", messageId, destination);
            if (!outgoingHeaders.TryGetValue("ServiceControl.RetryTo", out var retryTo))
            {
                retryTo = destination;
                outgoingHeaders.Remove("ServiceControl.TargetEndpointAddress");
            }
            else
            {
                Log.DebugFormat("{0}: Found ServiceControl.RetryTo header. Rerouting to {1}", messageId, retryTo);
            }

            var transportOp = new TransportOperation(outgoingMessage, new UnicastAddressTag(retryTo));

            await sender.Dispatch(new TransportOperations(transportOp), message.TransportTransaction, message.Extensions)
            .ConfigureAwait(false);

            Log.DebugFormat("{0}: Forwarded message to {1}", messageId, retryTo);
        }
예제 #9
0
        Task CloneAndSendLocal(byte[] body, Dictionary <string, string> headers, Site destinationSite, TransportTransaction transportTransaction, IDispatchMessages dispatcher)
        {
            headers[Headers.DestinationSites] = destinationSite.Key;

            var message   = new OutgoingMessage(headers[Headers.MessageId], headers, body);
            var operation = new TransportOperation(message, new UnicastAddressTag(inputAddress));

            return(dispatcher.Dispatch(new TransportOperations(operation), transportTransaction, new ContextBag()));
        }
예제 #10
0
        Task DispatchMailMessage(MessageContext messageContext, MailMessage newMessage)
        {
            var serializedMessage = Serialize(newMessage);
            var operation         = new TransportOperations(
                new TransportOperation(
                    message: new OutgoingMessage(messageContext.MessageId, messageContext.Headers, serializedMessage),
                    addressTag: new UnicastAddressTag("Mail")));

            return(dispatchMessages.Dispatch(operation, new TransportTransaction(), new ContextBag()));
        }
예제 #11
0
        public void RunReport(MetricsData metricsData, Func <HealthStatus> healthStatus, CancellationToken token)
        {
            var serialized = JsonBuilderV2.BuildJson(metricsData);
            var body       = Encoding.UTF8.GetBytes(serialized);

            var headers   = new Dictionary <string, string>();
            var message   = new OutgoingMessage(Guid.NewGuid().ToString(), headers, body);
            var operation = new TransportOperation(message, new UnicastAddressTag(destination));
            var task      = dispatcher.Dispatch(new TransportOperations(operation), new TransportTransaction(), new ContextBag());

            task.GetAwaiter().GetResult();
        }
예제 #12
0
        async Task RawSending(IDispatchMessages dispatcher)
        {
            #region DispatcherRawSending

            Dictionary<string, string> headers = new Dictionary<string, string>();
            OutgoingMessage outgoingMessage = new OutgoingMessage("MessageId", headers, new byte[]
            {
            });
            NonDurableDelivery[] constraints =
            {
                new NonDurableDelivery()
            };
            UnicastAddressTag address = new UnicastAddressTag("Destination");
            TransportOperation transportOperation = new TransportOperation(outgoingMessage, address, DispatchConsistency.Default, constraints);
            TransportOperations operations = new TransportOperations(transportOperation);
            await dispatcher.Dispatch(operations, new ContextBag());

            #endregion
        }
예제 #13
0
        static async Task OnMessage(MessageContext context, IDispatchMessages dispatcher)
        {
            Console.WriteLine($"Received FooEvent with ID {context.MessageId}, sleeping 30ms to simulate normal usage");

            await Task.Delay(30);

            var numberOfEventsToPublish = 10;
            var events = Enumerable.Range(1, numberOfEventsToPublish).Select(_ => new BarEvent {
                Id = Guid.NewGuid().ToString()
            });

            var tasks = new List <TransportOperation>(numberOfEventsToPublish);

            tasks.AddRange(events.Select(@event => new TransportOperation(new OutgoingMessage(@event.Id, new Dictionary <string, string>(), new byte [] { 1, 2, 3 }), new MulticastAddressTag(typeof(BarEvent)))));

            await dispatcher.Dispatch(new TransportOperations(tasks.ToArray()), context.TransportTransaction, context.Extensions);

            Console.WriteLine($"Published {numberOfEventsToPublish} BarEvent events.");
        }
예제 #14
0
        async Task RawSending(IDispatchMessages dispatcher)
        {
            #region DispatcherRawSending

            Dictionary <string, string> headers         = new Dictionary <string, string>();
            OutgoingMessage             outgoingMessage = new OutgoingMessage("MessageId", headers, new byte[]
            {
            });
            NonDurableDelivery[] constraints =
            {
                new NonDurableDelivery()
            };
            UnicastAddressTag   address            = new UnicastAddressTag("Destination");
            TransportOperation  transportOperation = new TransportOperation(outgoingMessage, address, DispatchConsistency.Default, constraints);
            TransportOperations operations         = new TransportOperations(transportOperation);
            await dispatcher.Dispatch(operations, new ContextBag());

            #endregion
        }
                protected override Task OnStart(IMessageSession session)
                {
                    // Simulating a v3.3 control message
                    var body            = Encoding.UTF8.GetBytes(@"<?xml version=""1.0""?>
<Messages xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns=""http://tempuri.net/NServiceBus.Unicast.Transport"">
    <CompletionMessage>
        <ErrorCode>5</ErrorCode>
    </CompletionMessage>
</Messages>");
                    var outgoingMessage = new OutgoingMessage("0dac4ec2-a0ed-42ee-a306-ff191322d59d\\47283703", new Dictionary <string, string>
                    {
                        { "NServiceBus.ControlMessage", "True" },
                        { "NServiceBus.ReturnMessage.ErrorCode", "5" },
                        { "NServiceBus.ContentType", "text/xml" }
                    }, body);

                    var endpoint = Conventions.EndpointNamingConvention(typeof(TestingEndpoint));

                    return(dispatcher.Dispatch(new TransportOperations(new TransportOperation(outgoingMessage, new UnicastAddressTag(endpoint))), new TransportTransaction(), new ContextBag()));
                }
        public async Task <ErrorHandleResult> OnError(IErrorHandlingPolicyContext handlingContext, IDispatchMessages dispatcher)
        {
            await Task.Delay(1000);

            if (handlingContext.Error.ImmediateProcessingFailures < immediateRetries)
            {
                return(ErrorHandleResult.RetryRequired);
            }

            logger.Error("Error processing a message. Continuing in throttled mode.", handlingContext.Error.Exception);

            //Move to back of the queue.
            var incomingMessage = handlingContext.Error.Message;
            var message         = new OutgoingMessage(incomingMessage.MessageId, incomingMessage.Headers, incomingMessage.Body);
            var operation       = new TransportOperation(message, new UnicastAddressTag(inputQueue));

            await dispatcher.Dispatch(new TransportOperations(operation), handlingContext.Error.TransportTransaction, new ContextBag())
            .ConfigureAwait(false);

            return(ErrorHandleResult.Handled);
        }
        static async Task OnOutgoingMessage(MessageContext delayedMessage, IDispatchMessages dispatcher)
        {
            string dueHeader;
            string destination;
            var    headers = delayedMessage.Headers;

            if (!headers.TryGetValue("NServiceBus.Raw.DelayedRetries.Due", out dueHeader) ||
                !headers.TryGetValue("NServiceBus.Raw.DelayedRetries.RetryTo", out destination))
            {
                //Skip
                return;
            }
            var due       = DateTime.Parse(dueHeader).ToUniversalTime();
            var sleepTime = due - DateTime.UtcNow;

            if (sleepTime > TimeSpan.Zero)
            {
                await Task.Delay(sleepTime).ConfigureAwait(false);
            }

            var    attempt = 1;
            string delayedRetryHeader;

            if (delayedMessage.Headers.TryGetValue("NServiceBus.Raw.DelayedRetries.Attempt", out delayedRetryHeader))
            {
                attempt = int.Parse(delayedRetryHeader);
            }
            attempt++;
            headers.Remove("NServiceBus.Raw.DelayedRetries.Due");
            headers.Remove("NServiceBus.Raw.DelayedRetries.RetryTo");
            headers["NServiceBus.Raw.DelayedRetries.Attempt"] = attempt.ToString();

            var message   = new OutgoingMessage(delayedMessage.MessageId, headers, delayedMessage.Body);
            var operation = new TransportOperation(message, new UnicastAddressTag(destination));
            await dispatcher.Dispatch(new TransportOperations(operation), delayedMessage.TransportTransaction, delayedMessage.Extensions).ConfigureAwait(false);
        }
예제 #18
0
        async Task RawSending(IDispatchMessages dispatcher)
        {
            #region DispatcherRawSending

            var headers         = new Dictionary <string, string>();
            var outgoingMessage = new OutgoingMessage("MessageId", headers, new byte[]
            {
            });
            var constraints = new List <DeliveryConstraint>
            {
                new NonDurableDelivery()
            };
            var address   = new UnicastAddressTag("Destination");
            var operation = new TransportOperation(
                message: outgoingMessage,
                addressTag: address,
                requiredDispatchConsistency: DispatchConsistency.Default,
                deliveryConstraints: constraints);
            var operations = new TransportOperations(operation);
            await dispatcher.Dispatch(operations, new TransportTransaction(), new ContextBag())
            .ConfigureAwait(false);

            #endregion
        }
예제 #19
0
        public async Task RawSending()
        {
            IDispatchMessages dispatcher = null;

            #region DispatcherRawSending

            var headers         = new Dictionary <string, string>();
            var outgoingMessage = new OutgoingMessage("MessageId", headers, new byte[]
            {
            });
            var constraints = new[]
            {
                new NonDurableDelivery()
            };
            UnicastAddressTag         address                             = new UnicastAddressTag("Destination");
            TransportOperation        transportOperation                  = new TransportOperation(outgoingMessage, address, DispatchConsistency.Default, constraints);
            UnicastTransportOperation unicastTransportOperation           = new UnicastTransportOperation(outgoingMessage, "destination");
            IEnumerable <MulticastTransportOperation> multicastOperations = Enumerable.Empty <MulticastTransportOperation>();
            UnicastTransportOperation[] unicastOperations                 = { unicastTransportOperation };
            TransportOperations         operations                        = new TransportOperations(multicastOperations, unicastOperations);
            await dispatcher.Dispatch(operations, new ContextBag());

            #endregion
        }
예제 #20
0
 Task Dispatch(TransportOperation[] transportOperations, IExtendable context)
 {
     return(dispatcher.Dispatch(new TransportOperations(transportOperations), new TransportTransaction(), context.Extensions));
 }
        public Task Dispatch()
        {
            var replyOperations = replies.Select(CreateReplyOperation).ToArray();

            return(dispatcher.Dispatch(new TransportOperations(replyOperations), new TransportTransaction(), new ContextBag()));
        }