Question

Background:

We have a messaging subsystem based on MassTransit. It works great, pumps thousands of messages with only minor issues. So far, failed messages were automatically pushed to xxx_error queues. This also works great.

We even had our own web-based management console to peek into message queues and resend failed messages. The tool was based on the BusDriver example and worked directly on MSMQ - it copies messages from xxx_error to xxx and they are resent.

Current situation:

We consider moving to RabbitMQ, it seems faster and more scalable. But of course, the MSMQ management console becomes useless, I don't like to write yet another version of the console to work on RabbitMQ queues. I would rather go with a generic route where I put failed messages into my own repository which would be independent on the MSMQ transport.

Sounds easy. And this is where we have a specific question.

The repository of failed messages will contain (among other attributes) the message body and the message subscriber name. Later, I can go to the repository, deserialize the message and resend it to a specific subscriber.

But, we don't want to bus.Publish( msg ) as the message would again hit all subscribers rather than the one which failed previously. What we want is to resend the message to precisely one subscriber.

This seems possible with:

senderbus.GetEndpoint( new Uri( "rabbitmq://servername/subscriber1" ) ).Send( msg );

or

senderbus.GetEndpoint( new Uri( "msmq://localhost/subscriber1" ) ).Send( msg );

(depending on the transport used). With this approach, the message is delivered to the only specific subscriber.

The question is:

Would this be the recommended approach? What alternatives do we have?

The possible problem is that this approach probably ignores the information on current subscriptions and delivers the message directly to the subscriber queue. However, the subscriber possibly no longer subscribes to messages of the type. So, the code should possibly be something like:

if ( subscriber1 still subscribes to messages of msg.GetType() ) <- how do to this?
   senderbus.GetEndpoint( new Uri( "rabbitmq://servername/subscriber1" ) ).Send( msg );

Thanks in advance for any comments on this.

Was it helpful?

Solution

I wouldn't.

Not sure how much your management console is doing, but RabbitMQ's console can do everything but move messages from queue to queue. I'm on the look out for that functionality myself, hoping there's a script I could use specifically for that.

One tricky thing to keep in mind is the fact that endpoint != consumer. An endpoint serves all consumers on that bus and while endpoint address would be trivial to store and republish into, an individual consumer would not.

What people suggest is idempotent consumers: http://en.wikipedia.org/wiki/Idempotence#Computer_science_meaning

I would not worry about consumer not subscribing to a particular message, with static typing employed for establishing routing information you are looking at upgrade. Take care of those messages as part of your upgrade process.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top