This issue proposes adding a new method, Response.Reject(error), which logs the error and explicitly re-queues the command request.
Background
The Response interface provides three ways to send a response to a command request:
Done - send a successful response with a payload, Close() is equivalent to calling Done(nil)
Failure - send an error response indicating an "expected" in-domain error
Error - send an error indicating an unexpected runtime error
If a command handler does not call one of these methods, the request is re-delivered, potentially to a different peer. This is the only way to cause a request to be re-queued, short of crashing. The Rinq API does not provide a way to indicate that a command failed, without acknowledging the request and sending a response.
Known Issues
There are some problems associated with re-queuing messages. Most notably, it is possible for messages that do not have a deadline (TTLs) to "bounce" on and off the queue forever if they repeatedly hit command handlers that do not send a response. Note that this issue is already present.
The AMQP spec does not provide a count of redeliveries, so it's not possible to stop re-queuing after a certain number of retries, however RabbitMQ does provide a dead-letter feature, which allows a message to be re-delivered to a different exchange (the "dead-letter exchange") when it is rejected. We may be able to use this to "shelve" a valid but problematic request after some configurable number of rejections.
Once the issue that caused the error has been resolved, these "shelved" requests could be explicitly triggered for redelivery by the application.
This issue proposes adding a new method,
Response.Reject(error)
, which logs the error and explicitly re-queues the command request.Background
The
Response
interface provides three ways to send a response to a command request:Done
- send a successful response with a payload,Close()
is equivalent to callingDone(nil)
Failure
- send an error response indicating an "expected" in-domain errorError
- send an error indicating an unexpected runtime errorIf a command handler does not call one of these methods, the request is re-delivered, potentially to a different peer. This is the only way to cause a request to be re-queued, short of crashing. The Rinq API does not provide a way to indicate that a command failed, without acknowledging the request and sending a response.
Known Issues
There are some problems associated with re-queuing messages. Most notably, it is possible for messages that do not have a deadline (TTLs) to "bounce" on and off the queue forever if they repeatedly hit command handlers that do not send a response. Note that this issue is already present.
The AMQP spec does not provide a count of redeliveries, so it's not possible to stop re-queuing after a certain number of retries, however RabbitMQ does provide a dead-letter feature, which allows a message to be re-delivered to a different exchange (the "dead-letter exchange") when it is rejected. We may be able to use this to "shelve" a valid but problematic request after some configurable number of rejections.
Once the issue that caused the error has been resolved, these "shelved" requests could be explicitly triggered for redelivery by the application.
/cc @ezzatron @koden-km