watermill
watermill copied to clipboard
Allow choosing the nack method
Hello, I would like to be able to choose the Nack method used depending on the message processing.
Example
// file: watermill/message.go
type Message strut {}
func (m *Message) Nack(method NackMethod) {
m.nack <- method
}
// file: watermill-amqp/subscriber.go
// Here we can handle the method
// file: handler.go
func handler(msg *message.Message) error {
// ...
msg.Nack(message.NackRequeue)
msg.Nack(message.NackDiscard)
msg.Nack(message.NackDelay(5*time.Minute))
}
With this example implementation, nack will return a method and the subscriber can:
- either handle it and support the method
- default to it's default nack method if it doesn't support discard or delay for example
Of course this is just an example, but with method like this, we should be able to override the nack method used.
This can be used in subscriber like:
- amqp with
amqp.NackDiscardandamqp.NackRequeue - nats with
nats.Term(),nats.InProgress(),nats.Nak()andnats.NakWithDelay()
Middleware example
To make this easier to use, we can make use of it via middleware. For example, an handler can return an error, and the middleware will choose the best method for the ack.
func handler(msg *message.Message) error {
return ErrShouldRequeue
}
func middleware(h message.HandlerFunc) message.HandlerFunc {
return func(msg *message.Message) error {
err := h(msg)
if errors.Is(err, ErrShouldRequeue) {
msg.Nack(message.NackRequeue)
}
return err
}
}