I need to call a RabbitMQ RPC Service from within a C# WCF Web service hosted in IIS.
We have this working OK, but being a good little soldier I was reading the RabbitMQ client documentation and it states the following “IModel should not be shared between threads”.
My understanding is that in RabbitMQ an IModel is actually a socket connection.
this would mean that for every call the WCF service makes it’s needs to create an IModel and dispose of it once completed.
This would seem to me to be somewhat excessive on performance and socket usage and I am wondering if my understanding is actually correct, or if there are other options available like using a connection pool of IModels between threads.
Any suggestions would be gratefully received. Here’s a sample of the code I’m using below, the rabbitMQ connection is actually initialized in the Global.asax, I just have it there to you can see the usage.
var connectionFactory = new ConnectionFactory();
connectionFactory.HostName = "SampleHostName";
connectionFactory.UserName = "SampleUserName";
connectionFactory.Password = "SamplePassword";
IConnection connection = connectionFactory.CreateConnection();
// Code below is what we actually have in the service method.
var model = connection.CreateModel();
using (model)
{
model.ExchangeDeclare("SampleExchangeName", ExchangeType.Direct, false);
model.QueueDeclare("SampleQueueName", false, false, false, null);
model.QueueBind("SampleQueueName", "SampleExchangeName", "routingKey" , null);
// Do stuff, like post messages to queues
}
This is incorrect. IConnection represents a connection 🙂 Model was introduced in order to allow several clients to use the same tcp connection. So Model is a “logical” connection over a “physical” one.
One of tasks Model does is splitting and re-assembling large messages. If message exceeds certain size, it is split into frames, frames are labeled and are assembled back by receiver. Now, imagine that 2 threads send large messages… Frame numbers will be messed up, and you will end up with Frankenstein message which consists of random parts of 2 messages.
You are right assuming that Model creation have some cost. Client sends a request to server to create a model, server creates a structure in memory for this model, and sends model Id back to the client. It is done over tcp connection which is already open, so no overhead due to establishing connection. But there is still some overhead because of network round trip.
I’m not sure about WCF binding, but base rabbit’s .net library does not provide any pooling for models. If it is a problem in your case, you’ll have to come up with something on your own.