Sending or publishing from API controller

We have some API endpoints that should send or publish a message.
Reading through these pages: one, two, and the page about async handlers (sorry, can only put two links in a post as a new user).
These make us think we should always use the option to RequireImmediateDispatch when sending from an API controller, as theoretically not using that could cause the message to be lost, if the API call succeeds but the async send batch fails to send the API call succeeding first means it’s untraceable? Is that thinking correct or are we missing something?

NServiceBus outgoing message batching has no effect on messages sent outside of the message handler. Each operation will be an immediate dispatch and a failure would result in an exception raised to the sending code, or API controller in your case. The only way to send a “batch” would be to have a collection of sending tasks. And even then, if one of the tasks fails, it will throw in the controller code. Hope that helps.

Thanks Sean, that’s clear. The documentation seems to suggest otherwise I think, or maybe I don’t fully see it. The blue note is within the Outside a message handler section.

I can see how it can be not very clear. Especially this sentence

When the invocation ends, it does not mean that the message has actually been sent.

Let’s take ASB (I assume you’re using ASB transport). When you send outside a message handler, there’s no unit of work or transaction of any sort around the send operation. That’s why each send is an immediate dispatch. If you’d have more than one message sent out, they’d all be sent one-by-one and immediately.

One exception I can think of would be MSMQ. MSMQ transport doesn’t actually send but rather stores first and then forwards. I’ll try to get more clarification on that note.

@Jan-Pieter_Zoutewell, I’ve raised an issue to clarify that note as it doesn’t seem to be right the way it is right now. Thank you for bringing it up.

Getcha, thanks Sean!

QQ, if we were to run our own transaction, without explicitly supplying it towards NServiceBus, would that affect this somehow? EG:

using (var transaction = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
    messageSession.Send();
}

Operations within a transaction scope will be batched together by the underlying ASB SDK indeed. You will be limited to 100 messages if I’m not mistaken but those will be sent atomically and would only be able to target a single destination.

This slots it together, thanks for clarifying Sean.