MQ remove message after all consumers are finished processing

We have the following scenario:

A service publishes a message to the RequestCompleted queue.

Multiple consumers need to handle the same message, e.g.

  • Send email
  • Generate document

After all the consumers have done their processing of the message, it should be removed from the queue and the service notified that all further processing has been done. If any of the consumers fail, the message can be retried.

Do you have any suggestions for how to implement this using ServiceStack’s messaging? (We’re currently using RabbitMQ.)

I wouldn’t treat the MQ’s like a state machine, they’re more like a work queue to process background tasks.

I’d keep the state of what’s done or needs to be done with a row in the database with columns containing the date when each task was completed. When first starting the task I’d insert the row representing the task and fire off a new MQ Message for each sub task that needs to be done (e.g. GenerateDocument, SendEmail, etc) that also passes the task row id so that the Message Handler can populate the completed date after it has successfully completed the sub task. You’ll know all tasks have completed when all fields are populated.

If there’s an error processing one of the messages the RabbitMQ Server should automatically retry it it, if that also fails the message gets sent to that messages DLQ. You could inspect the DLQ’s to identify/resolve any errors or you could fire off a hourly/daily task that goes through any uncompleted tasks and fire off new MQ Messages for any sub tasks that doesn’t have a completed date.

1 Like