Author |
Message
|
kayoumt |
Posted: Thu Aug 27, 2009 9:34 pm Post subject: XMS/C# Sessions performance |
|
|
Voyager
Joined: 18 Sep 2007 Posts: 81
|
Hi,
I have some performance issues in my C#/XMS application. I suspect that the reason of that performance problem is : XMS sessions wait long time before getting CPU. I did not have that slowness when my MQ application was built with .NET "threads".
The main component of my application is a C# form (GUI). The form sends request sometimes by a "Producer Session" and listens publish/subscribe messages by "Consumer Session". When the form sends requests and waits for response, it loops by calling "Application.DoEvents" (to give CPU to threads). Note also that the two sessions are started when the application is started and are stopped when the application is stopped.
Despite of that simple and clean architecture of threads, sending a request (message sent point-to-point) and getting a response (message published by a server) can take more than 10 seconds. My application and the MQServer are running on laptop with Core2Duo Processor.
What I did not understand in XMS Sessions ???
Thanks in advance for any help. |
|
Back to top |
|
 |
shashikanth_in |
Posted: Fri Aug 28, 2009 7:19 am Post subject: |
|
|
Centurion
Joined: 26 Feb 2009 Posts: 123
|
Are you using asynchronous message listener or calling a synchronous consumer.receive method? You might want to avoid calling DoEvents method.
Finally you might want to callup IBM Service for further help. |
|
Back to top |
|
 |
kayoumt |
Posted: Fri Aug 28, 2009 1:38 pm Post subject: |
|
|
Voyager
Joined: 18 Sep 2007 Posts: 81
|
shashikanth_in,
1) Waiting for my request by looping calling "Application.DoEvents" and 2) Starting a thread which does synchronous consumer.receive. I do not see the difference between the two solutions ? |
|
Back to top |
|
 |
shashikanth_in |
Posted: Sun Aug 30, 2009 4:54 am Post subject: |
|
|
Centurion
Joined: 26 Feb 2009 Posts: 123
|
Instead of looping, you can use the asynchronous messaging for receiving response.
You create a consumer for receiving response publication and set a message listener for that. Message listener will be called whenever there is a publication. This avoids creating another thread for receiving publication synchronously.
The following piece of code might help if you decide to go for Aysnchronouse messaging:
try
{
// Some code
IMessageConsumer consumer = session.CreateConsumer(destination) ;
MessageListener messageListener = new MessageListener(OnNewMessageCallback);
consumer.MessageListener = messageListener;
// some more code
}
// Message callback
private void OnNewMessageCallback(IMessage message)
{
// Do message processing here.
}
HTH. |
|
Back to top |
|
 |
kayoumt |
Posted: Sun Aug 30, 2009 9:03 am Post subject: |
|
|
Voyager
Joined: 18 Sep 2007 Posts: 81
|
Hi shashikanth_in,
Thanks for the code you posted. I exactly did what you are suggesting. But, this is only one side of my application. Let me briefly explain you the two sides.
// Session1
DateTime startTime = DateTime.Now;
DateTime endTime = DateTime.Now;
while (((TimeSpan)(endTime - startTime)).TotalSeconds < m_delay)
{
IMessage var_message = m_reply_consumer.Receive(1);
if (var_message != null)
// Do something with the message
else
Application.DoEvents();
endTime = DateTime.Now;
}
// Calling DoEvents helps me avoid the main thread of my application wait m_delay time without doing nothing.
// Session2
// Message callback
private void OnNewMessageCallback(IMessage message)
{
m_reply_producer.Send(p_message);
}
// Main Thread - Common stuff
m_reply_queue = Session1.CreateTemporaryQueue();
m_reply_destination = Session2.CreateTopic("*/RP*");
m_reply_consumer = Session2.CreateConsumer(m_reply_destination);
m_reply_producer = Session2.CreateProducer(m_reply_queue);
May be the trouble is in the two red lines ? The temporary queue is created by Session1, but the producer (on the temporary queue) is created by Session2. |
|
Back to top |
|
 |
fjb_saper |
Posted: Sun Aug 30, 2009 2:29 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
You should take a look at a JMS tutorial, that would really help you.
You use
Code: |
m_reply_queue = Session1.CreateTemporaryQueue(); |
Note that the lifetime of m_reply_queue is that of session1. I would not consider using it in session2. As well depending on the open mode (share | exclusive) you may not be able to access it from session 2...
- Check your application. Looping around a receive is not good practice.
You should set the right amount of time in the receive... (like receiver.receive(1000).
- Make sure before attempting a receive to have the connection you are using in started status.
- If you plan on using multiple threads assign a connection to each thread.
- On request/reply: if you are using a transacted session make sure to call session.commit() between the send and the corresponding receive.
Both send and receive should happen on the same thread.
Have fun  _________________ MQ & Broker admin |
|
Back to top |
|
 |
kayoumt |
Posted: Sun Aug 30, 2009 6:52 pm Post subject: |
|
|
Voyager
Joined: 18 Sep 2007 Posts: 81
|
fjb_saper,
Thanks for all hints.
Quote: |
Check your application. Looping around a receive is not good practice.
You should set the right amount of time in the receive... (like receiver.receive(1000).
|
If yo use receive with a big delay in a thread running a windows GUI (form), without using Looping + DoEvents, the form will freeze while your thread is waiting for messages.
I could avoid using Looping+DoEvents by starting a thread which runs the receive (big_delay) method. But, anyway, my "main" thread (which started the "receiver thread") needs to have some kind of "passive looping" for waiting the end of the thread while not making freeze the form. |
|
Back to top |
|
 |
fjb_saper |
Posted: Sun Aug 30, 2009 8:07 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
What's the problem with the form being frozen while waiting for the reply?
Just make sure you set the hourglass before you go into the receive method...
The time for a wait there should not exceed 2 seconds...
Why would you need to wait longer? How long on average does the server process take?  _________________ MQ & Broker admin |
|
Back to top |
|
 |
kayoumt |
Posted: Sun Aug 30, 2009 8:48 pm Post subject: |
|
|
Voyager
Joined: 18 Sep 2007 Posts: 81
|
fjb_saper,
I do not think the value of the timeout or the behavior of the form (frozen or not) have direct relationship with my XMS performance.
The problem is to know how do I use XMS stuff for making my application run as faster as it was running before I migrated to XMS ?
When I started learning XMS, I did understand that a Session is a kind of Thread. I suspect that :
1) There's something making sessions slow in my application ?
2) The producer/consumer communication of the two sessions by temporary queue is blocking sometimes somewhere ?
3) Two sessions and a main thread (for Form) is too much in a XP dual core2 laptop ?
4) Calling DoEvents do not give back CPU to sessions ? |
|
Back to top |
|
 |
kayoumt |
Posted: Sun Aug 30, 2009 8:52 pm Post subject: |
|
|
Voyager
Joined: 18 Sep 2007 Posts: 81
|
Forget about this hypothesis :
Quote: |
4) Calling DoEvents do not give back CPU to sessions ?
|
I did a test without DoEvents and it is still slow. |
|
Back to top |
|
 |
bruce2359 |
Posted: Mon Aug 31, 2009 6:37 am Post subject: |
|
|
 Poobah
Joined: 05 Jan 2008 Posts: 9469 Location: US: west coast, almost. Otherwise, enroute.
|
Quote: |
The problem is to know how do I use XMS stuff for making my application run as faster as it was running before I migrated to XMS ? |
How much faster?
What else has changed in your environment? New apps? New db?
Other apps experiencing longer response times? _________________ I like deadlines. I like to wave as they pass by.
ב''ה
Lex Orandi, Lex Credendi, Lex Vivendi. As we Worship, So we Believe, So we Live. |
|
Back to top |
|
 |
kayoumt |
Posted: Mon Aug 31, 2009 8:28 am Post subject: |
|
|
Voyager
Joined: 18 Sep 2007 Posts: 81
|
bruce2359,
The only thing I changed is : using XMS API instead of MQ API + native RFH.
About performance :
- My Server (C++) has the same performance than before. It is simpler ; it reads message requests from a Consumer (persistent queue) and send responses on a Publisher (topic destination).
- The Client (C#) is at least 40 times slower than before. I already explained how the it works in the thread. |
|
Back to top |
|
 |
fjb_saper |
Posted: Mon Aug 31, 2009 12:50 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
Again, This is due to your coding and the handling of connections, sessions and threads...
You really need to look on the web for JMS performance information and maybe a JMS tutorial. It will help you understand what we would spend hours explaining. XMS works much in the same way as JMS!.
Have fun  _________________ MQ & Broker admin |
|
Back to top |
|
 |
kayoumt |
Posted: Mon Aug 31, 2009 5:01 pm Post subject: |
|
|
Voyager
Joined: 18 Sep 2007 Posts: 81
|
Thanks a lot for your help fjb_saper. I'll keep debugging my code. I'll also try to improve my knowledge in XMS/JMS. |
|
Back to top |
|
 |
fjb_saper |
Posted: Mon Aug 31, 2009 7:38 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
as a better hint my earlier point
Quote: |
If you plan on using multiple threads assign a connection to each thread |
should really read as:
Make sure each thread has it's own connection.
Connection sharing might look nice when you program it, but is really bad for performance. Imagine the connection as a funnel. Now think that every API call has to go through
Code: |
synchronized(connection){....} |
Not ideal for a multi-thread high performance app is it?  _________________ MQ & Broker admin |
|
Back to top |
|
 |
|