rebus-org / Rebus

:bus: Simple and lean service bus implementation for .NET
https://mookid.dk/category/rebus
Other
2.31k stars 359 forks source link

We get MessageCouldNotBeDispatchedToAnyHandlersException but retrying it works #1128

Closed NextFreeUsername closed 8 months ago

NextFreeUsername commented 9 months ago

We use Rebus version 7.2.1 with Rebus.SqlServer 7.3.1

The following message gives the included exception: Header { "rbs2-msg-priority": "2", "rbs2-intent": "pub", "rbs2-msg-id": "bf12970a-9c85-41cf-9563-67c79cfca259", "rbs2-return-address": "[Clients].[Messages]", "rbs2-senttime": "2023-12-20T09:52:08.9695400+01:00", "rbs2-sender-address": "[Clients].[Messages]", "rbs2-msg-type": "SharedCode.Rebus.CacheInvalidatedEvent, SharedCode.Rebus", "rbs2-corr-id": "bf12970a-9c85-41cf-9563-67c79cfca259", "rbs2-corr-seq": "0", "rbs2-content-type": "application/json;charset=utf-8", "rbs2-error-details": "System.AggregateException: 1 unhandled exceptions (Message with ID bf12970a-9c85-41cf-9563-67c79cfca259 and type SharedCode.Rebus.CacheInvalidatedEvent, SharedCode.Rebus could not be dispatched to any handlers (and will not be retried under the default fail-fast settings))\n ---> Rebus.Exceptions.MessageCouldNotBeDispatchedToAnyHandlersException: Message with ID bf12970a-9c85-41cf-9563-67c79cfca259 and type SharedCode.Rebus.CacheInvalidatedEvent, SharedCode.Rebus could not be dispatched to any handlers (and will not be retried under the default fail-fast settings)\n at Rebus.Pipeline.Receive.DispatchIncomingMessageStep.Process(IncomingStepContext context, Func1 next)\n at Rebus.Events.Steps.MessageReceivedStep.Process(IncomingStepContext context, Func1 next)\n at Rebus.Sagas.LoadSagaDataStep.Process(IncomingStepContext context, Func1 next)\n at Rebus.Pipeline.Receive.ActivateHandlersStep.Process(IncomingStepContext context, Func1 next)\n at Rebus.Pipeline.Receive.HandleRoutingSlipsStep.Process(IncomingStepContext context, Func1 next)\n at Rebus.Pipeline.Receive.DeserializeIncomingMessageStep.Process(IncomingStepContext context, Func1 next)\n at Rebus.Auditing.Messages.IncomingAuditingStep.Process(IncomingStepContext context, Func1 next)\n at Rebus.DataBus.ClaimCheck.HydrateIncomingMessageStep.Process(IncomingStepContext context, Func1 next)\n at Rebus.Pipeline.Receive.HandleDeferredMessagesStep.Process(IncomingStepContext context, Func1 next)\n at Rebus.Retry.FailFast.FailFastStep.Process(IncomingStepContext context, Func1 next)\n at Rebus.Retry.FailFast.FailFastStep.Process(IncomingStepContext context, Func1 next)\n at Rebus.Retry.Simple.SimpleRetryStrategyStep.DispatchWithTrackerIdentifier(Func1 next, String identifierToTrackMessageBy, ITransactionContext transactionContext, String messageId, String secondLevelMessageId)\n --- End of inner exception stack trace ---", "rbs2-source-queue": "[Performances].[Messages]" }

Body { "CacheType": 29 }

I don't see any reason why this occurs. When I take the same message and move it from the DLQ into the input queue, it simply gets processed without an issue. Locally it works 100% of the time, I can step through all code, it works like it should. How can I figure out what is going on?

mookid8000 commented 9 months ago

This sounds like something that would happen if you were running two different Rebus instances with the same input queue. Sometimes the message would be consumed by the correct Rebus instance, sometimes the wrong Rebus instance.

Could it be something like that?

NextFreeUsername commented 8 months ago

Ok that's it. We have 1 API "A" publishing and subscribing to a queue and we have 1 other API "B" publishing only to that same queue. Apparently since the recent upgrade of Rebus, the API "B" also reads from the queue although the code has no subscriptions. It indeed throws this error when I publish an event to that queue and only run the API "B". Thanks for the insight, I'll close the issue.

mookid8000 commented 8 months ago

Apparently since the recent upgrade of Rebus, the API "B" also reads from the queue although the code has no subscriptions

Rebus instances ALWAYS read from their input queue - that's what it's there for. It doesn't matter if there are subscriptions: If a message goes into a Rebus instance's input queue, then that Rebus instance will get the message. You can (and should 😉) think of the input queue as a channel for stuff that you want a particular Rebus instance to have. Whether or not stuff goes into that channel then gets determined by whether anyone SENDS directly to that channel, or whether anyone PUBLISHES something with a topic that the Rebus instance has subscribed to.

I hope it's clear to you know how these things work. 🙂