I have an application that I'd like to consume messages from queue A, but if queue A is empty, I'd like it to consume messages from queue B instead of sitting idle. I only ever want it to process 1 message at a time, and if the consumer is busy processing a message (from either queue), other pending messages (on either queue) should remain on their queue until the consumer is idle again (this gives other consumers a chance to process the new message).
So, for example, if a message arrives on either queue A or queue B while the consumer is idle (waiting), then the consumer picks it up. If a message arrives on either queue while the consumer is currently processing a message, nothing happens until the consumer has finished processing the current message. And if a message is available on both queue A and queue B, the consumer prefers to pick the message from queue A.
Edit: actually I'd be equally happy to be informed that messages are available to consume on both A & B, and implement my own logic to choose which one I actually want to pull from the queue.
Subscribing to both queues at once in separate threads doesn't appear to work because:
- if a message M arrives on queue A, the consumer will have to unsubscribe from queue B while it's processing message M, then resubscribe once message M is handled. Otherwise, if a message arrives on queue B, it might get picked up and dispatched simultaneously - I don't want to handle more than one message at a time.
- if a message arrives on both queues at once (or a message is already available on both queues when the consumer starts up or finishes processing the previous message), then it's possible that both messages will be picked up before the consumer has the chance to unsubscribe from queue B. If this happens I'd have to roll one of the messages back, but if this happens frequently the message will exceed the rollback count and get moved to a failure queue.
Ideally I'd like to generalise this to the N queues case. I'm interested in solutions that ideally work via JMS, but if I have to use the IBM MQ-specific API to do this that's OK too. Is there a usage pattern, or library, that will help achieve this? Are there alternative queueing approaches/techniques/technologies that allow it?
Pulling all messages off all queues and putting them onto a single queue is a no-go; we need to be able to clear individual queues independently, and different consumers may subscribe to different subsets of the N queues.