How to get only MQ messages which are older that 2 minutes in C# usig XMS.net?

2k Views Asked by At

I have created an application using IBM XMS.NET. All is good and I am able to read the mssages from queue. I want to read only those messages which are older that 2 mins from now. How to use selector in this case. Below is code I have created.

 var time = 120000; // 2 mins in miliseconds
 var currentTime = (DateTime.Now - DateTime.MinValue).TotalMilliseconds; // current time in milliseconds
 long finaltime = Convert.ToInt64(currentTime - time); // Time in milliseconds after substracting 2 minutes
var dtt = Convert.ToInt64(((new DateTime(1970, 01, 01, 01, 00, 00)) - DateTime.MinValue).TotalMilliseconds); // Time in miliseconds till 1970
 finaltime = finaltime - dtt;  // substracting milliseconds till 1976 as JMSTimestamp shows time after 1970
string selector = "JMSTimestamp <=" + finaltime.ToString();

Here selector is getting set as fixed value for example 1454322340382. How I can set selector to choose latest DateTime.Now and then look for message older that DateTime.Now - 2 minutes.

2

There are 2 best solutions below

2
On

Because the selector is passed as parameter at the time of creating consumer, it can be changed without closing and recreating the consumer.

MessageConsumer receiver;
receiver = session.createConsumer(stockQueue, selector);

Update:

Evaluation of selector expression happens during creation of consumer. The DateTime.Now - 2 expression evaluates to a fixed value and does not change. For example "JMSTimestamp <= 1454322340382". So when a consumer is created with that selection string, consumer will get only those messages that match the above condition.

While the above is fine. But when the consumer is getting messages, new messages can come into the queue. Those message may become older than 2 minutes by the time consumer attempts to get them. Consumer will not get those messages even though they are older than two minutes because their JMSTimestamp is higher, for example 1454666666666. To remove such messages you will have to close the consumer and create it again with updated selector condition.

Hope I am clear.

For your use case, I would go for MQ Base .NET API instead of XMS .NET. First browse messages and if a message is older than 2 minutes remove it.

  queueBrowse = queueManager.AccessQueue(strQueueName, MQC.MQOO_BROWSE + MQC.MQOO_INPUT_AS_Q_DEF + MQC.MQOO_FAIL_IF_QUIESCING);

  try
  {
      MQMessage msgBrowse = new MQMessage();
      MQGetMessageOptions mqgmoBrowse = new MQGetMessageOptions();
      mqgmoBrowse.Options = MQC.MQGMO_BROWSE_NEXT;
      queueBrowse.Get(msgBrowse, mqgmoBrowse);
      TimeSpan ts = DateTime.Now.ToUniversalTime().Subtract(msgBrowse.PutDateTime);
      if (ts.TotalMinutes > 2)
      {
          MQMessage msgDelete = new MQMessage();
          msgDelete.MessageId = msgBrowse.MessageId;
          MQGetMessageOptions mqgmo = new MQGetMessageOptions();
          mqgmo.MatchOptions = MQC.MQMO_MATCH_MSG_ID;
          queueBrowse.Get(msgDelete, mqgmo);
          Console.WriteLine("Message older than 2 minutes deleted");
       }
       else
       {
           Console.WriteLine("Message not older than 2 minutes");
       }
  }
  catch (MQException ex)
  {
  }
0
On

Selecting on those messages that are older than 2 minutes is probably the most inefficient way to look at those messages. You don't say why you want to do this. If you simply want to discard them, then I suggest you have the producer of the message add an expiry time on those messages. If you cannot get the producer of the message to change their application to do this, then consider using the CAPEXPRY administrative over-ride.

If you want to look at them, then browsing through all the messages and only operating on those which are the right age would be more efficient that selecting them I'm sure.