Dealing with "saga not found" scenarios - rebus

Are there any mechanisms in Rebus to deal with messages that would normally be handled by a saga but for which there is no current saga that matches the correlation property? Out of the box, I believe those messages are just consumed by Rebus but there is no visibility as to what happens with them.
i.e. NServiceBus has the IHandleSagaNotFound to allow endpoints to deal with this scenario

Unfortunately there's no way to handle that right now. As you've probably found out, a message is simply logged that Rebus could not find an existing saga data instance for the incoming message.

Related

Axon4 - Re-queue failed messages

In below scenario, what would be the bahavior of Axon -
Command Bus recieved the command
It creates an event
However messaging infra is down (say kafka)
Does Axon has re-queing capability for event or any other alternative to handle this scenario.
If you're using Axon, you know it differentiates between Command, Event and Query messages. I'd suggest to be specific in your question which message type you want to retry.
However, I am going to make the assumption it's about events, as your stating Kafka.
If this is the case, I'd highly recommend reading the reference guide on the matter, as it states how you can uncouple Kafka publication from actual event storage in Axon.
Simply put, use a TrackingEventProcessor as the means to publish events on Kafka, as this will ensure a dedicate thread is used for publication instead of the same thread storing the event. Added, the TrackingEventProcessor can be replayed, thus "re-process" events.

Does gRPC resend messages

A question related to the idempotence of serverside code, or the necessity of it. Either for gRPC in general, or specifically to the java implementation.
Is it possible that when we send a message once from a client, that it is handled twice by our service implementation?
Maybe this would be related to retries when service seems unavailable; or could be configured by some policy?
Right now, when you send a message from a client it will be seen (at most) once by the server. If you have idempotent methods, you will soon be able to specify a policy for automatic retries (design doc) but these retry attempts will not be enabled by default. You do not have to worry about the gRPC library sending your RPCs more than once unless you have this configured in your retry policy.
According to grpc-java/5724, the retry logic has already been implemented. The OP does it using a Map, that is not type safe. A better way would be as follows:
NettyChannelBuilder builder = NettyChannelBuilder.forAddress(host, port)
.enableRetry()
.maxRetryAttempts(3);
There are other retry configurations available on the NettyChannelBuilder.
There's also an example here, although it's pretty hard to find.

Rebus priority on message

Is it possible using Rebus to set priority on messages?
The scenario is that we have a queueworker singing documents, for different services, some of them witch the user awaits the result, and some that the signed document is just stored for later use.
It would then be nice to prioritize the messages of the users that awaits a response. Is this possible ?
We are using Rebus2 with Azure ServiceBus
Unfortunately, since Azure Service Bus does not natively support message prioritization, and implementing it with the priority queue pattern would be cumbersome, it cannot readily be done by setting a priority on a message.
A simple approach that works in the general case is to have separate Rebus instances for different priorities, where one particular instance could then be used to "fast-track" messages that need to overtake all the other messages.
The instances could have the exact same configuration, except they use different input queues. This way, the routing configuration (endpoint mappings) get to determine which priority a message gets.

Rebus Publish Exception Handling

Lets assume rebus could not publish message to rabbitmq or some other queue, what is the best practice to handle this exception.
I stopped rabbitmq service and rebus threw Aggregate exception. I can manually cacth this exception in try - catch block but is there a better solution to catch exceptions when such situations happened ?
First off: If you get an exception when initially sending/publishing a message (e.g. while handling a web request), there's nothing you can do, really. Sorry ;)
You should probably log - thoroughly - all the information you can, and then be sure to set up logging so that the information ends up in a file or in some other persistent log. And then you should have some kind of notification or a process in place that ensures that someone will at some point look at the log.
You should probably have this kind of logging in place, regardless of the type of work you do.
Depending on how important your information is, you could also set up some kind of retry mechanism (although you should be careful that you do not consume threads and too much memory while retrying). Also, since your web application should be able to be recycled at any time, you probably should not rely (too much) on retries.
You can do some things, though, in order to minimize the risk of ending up in a situation where you can't send/publish.
I can recommend that you use some kind of high-availability transport, like MSMQ (because it has local outgoing queues), RabbitMQ (with a shovel on each machine), or Azure Service Bus or Azure Storage Queues if you're in Azure.
Moreover - if you were using MSMQ, and you want to publish an event - I would recommend that you await bus.Send(theEvent) first, and then when you handle the message, you await bus.Publish(theEvent). This is because Rebus (with the MSMQ transport) needs to do a lookup in the subscription storage in order to get all subscribers for the given event. This is not a problem with RabbitMQ though, because Rebus will use Rabbit's topics to do pub/sub and will be just as safe as doing an ordinary send.
When you're sending/publishing from within a Rebus message handler, there is of course no problem, since the receive operation will be rolled back, and eventually the incoming message will end up in an error queue.
I hope that cast some light on the situation :)

Validating messages in an orchestration, or receive port

I've been working under the assumption that a message entering an orchestration was validated against the messages schema, only to realize recently that this is not the case. There doesn't appear to be a validate shape, so I'm wondering if there is a clean reusable pattern out there to implement this?
You can validate the messages on an XMLReceive pipeline, but unfortunately this requires specifying the DocumentSpecNames which can detract from the flexibility of the receive.
A workaround is to use a custom "ValidatingXmlPipeline" and add the XMLValidator pipeline component to it.
As per your original question, there is a config setting in btsntsvc.config under Debugging called ValidateSchemas when message variables are assigned. I can't say I've used this as it will probably impact performance.

Resources