Thursday, July 5, 2018

Help me optimize this MSMQ service

Our MSMQ service, tends to be a pain in the ass for us.

It halts/locks at times, and feels pretty slow at times.

Can you help optimize it? Would love some good suggestions, with an explanation.

Here is our code. Every queue has it's own Invoker that holds the logic, for that queue.

This code just iterates all queues, takes a message, does the logic, and deletes it at the end.

public void Run(string[] queues)

{

var invokerFactory = new InvokerFactory();

var locator = new TypeLocator();

Communicator.Instance.Start().ContinueWith(z =>

{

Parallel.ForEach(locator.Locate<MessageQueueAttribute>(), x =>

{

if (queues != null && !queues.Contains(x.Attributes.First().QueueName))

return;

// Build the invoker

var invoker = invokerFactory.Build<IMessageQueueInvoker>(x.Type);

// Find the attribute data

var attribute = x.Attributes.First();

// Get the queue

var queue = _messagingService.GetQueue(attribute.QueueName);

// Start a new thread

for (var i = 0; i < attribute.NumberOfHandlers; i++)

{

Task.Factory.StartNew(() => ExecuteTransaction(invoker, attribute, queue), TaskCreationOptions.LongRunning | TaskCreationOptions.AttachedToParent);

}

});

}).Wait();

}

public void Run()

{

Run(null);

}

private void ExecuteTransaction(IMessageQueueInvoker invoker, MessageQueueAttribute attribute, MessageQueue queue)

{

while (true)

{

try

{

// Begin transaction

using (var tx = new MessageQueueTransaction())

{

tx.Begin();

// Fecth message

var message = queue.Receive(TimeSpan.FromSeconds(5), tx);

// Map and invoke

using (var reader = new StreamReader(message.BodyStream))

{

var json = reader.ReadToEnd();

var command = JsonConvert.DeserializeObject(json, attribute.CommandType);

try

{

invoker.Invoke(command, message);

}

catch (Exception ex)

{

_messagingService.Send(string.Format("{0}___failed", attribute.QueueName), command);

OnFaulted(ex, queue.QueueName, json);

}

finally

{

// Finish the transaction

tx.Commit();

}

}

}

}

catch (MessageQueueException msmqEx)

{

if (msmqEx.MessageQueueErrorCode != MessageQueueErrorCode.IOTimeout)

{

OnFaulted(msmqEx, "CORE MSMQ EXCEPTION", string.Empty);

throw;

}

}

}

}

private void OnFaulted(Exception exception, string queueName, string queueItem)

{

RaygunClient.Send(exception, new List<string> { "Findroommate.MSMQ" }, new Dictionary<string, string> { { "QueueName", queueName }, { "QueueMessage", queueItem } });

_systemService.Logger.Log("Findroommate.MSMQ", "MessageQueue Failure", new

{

QueueName = queueName

}, exception);

}

Help me optimize this MSMQ service Click here
  • Blogger Comment
  • Facebook Comment

0 comments:

Post a Comment

The webdev Team