Reliability of command delivery?

If I use the “fire-and-forget” command dispatch API (the single-argument dispatch() method on a command bus) like the Axon docs recommend for maximum scalability, what reliability guarantees are there?

To be more specific, suppose the following happens:

  1. Incoming request arrives from client.
  2. Request handler dispatches some number of commands.
  3. Request handler returns a “request in progress” response to the client.
  4. The server gets restarted (e.g., due to hardware failure).

Will any unhandled commands be processed when the server comes back up, or will they be lost?

It seems like the answer is “they’ll be lost” because I don’t see any persistence mechanism for commands, nor any way to use something like AMQP for command delivery. (Events, on the other hand, do seem to provide better reliability guarantees.)

If I’m incorrect about that, can someone describe what the reliability mechanism is, or point me to the relevant section of the docs?

If I’m correct, does that mean that if I want to guarantee that any client request I acknowledge is actually processed by the server at some point, I need to avoid using the fire-and-forget API and instead have my client request handler wait for callbacks to be called on any outgoing commands before acknowledging a request to the client?

That seems like it effectively means my command handlers have to be synchronous, even if their completion is communicated back to the calling code via an async-friendly callback mechanism. Is that the right approach, or should I be doing something else?



with fire-and-forget, it’s up to the distribution mechanism to guarantee delivery. If you have a best-effort distribution (like JGroups), then there is absolutely no guarantee. In such a case, you could implement a gateway that uses a callback to register (and retry, if appropriate) dispatched commands. So basically, you’re avoiding the fire-and-forget approach on the CommandBus level.

Your client handler could be made asynchronous and commit a response when the callback is invoked. That way, you don’t waste threads (and resources) on waiting for a server to respond.