/// <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); }
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())); }
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); }
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); }
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(); } }
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); }
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())); }
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())); }
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(); }
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 }
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."); }
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); }
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 }
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 }
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())); }