Search code examples
c#.net-coreibm-mqxms

IBM XMS Receive method not returning messages immediately


I use IBM XMS to connect to a third party to send and receive messages.

UPDATE:

  • Client .Net Core 3.1
  • IBM XMS library version from Nuget. Tried 9.2.4 and 9.1.5 with same results
  • Same code used to work fine a week ago - so something must have changed in the MQ manager or somewhere in my infrastructure
  • SSL and client certificates

I have been using a receive with timeout for a while without problems but since last week I started to not see any messages to pick - even when they were there - but once I changed to the not timeout receive method I started again to pick messages every 5 minutes.

Looking at the XMS logs I can see the messages are actually read almost immediately with and without timeout but that XMS seems to be deciding to wait for those 5 minutes before returning the message...

I haven't changed anything in my side and the third party reassures they haven't either.

My question is: given the below code used to receive is there anything there that may be the cause of the 5 minutes wait? Any ideas on things I can try? I can share the XMS logs too if that helps.

// This is used to set the default properties in the factory before calling the receive method
        private void SetConnectionProperties(IConnectionFactory cf)
        {
            cf.SetStringProperty(XMSC.WMQ_HOST_NAME, _mqConfiguration.Host);
            cf.SetIntProperty(XMSC.WMQ_PORT, _mqConfiguration.Port);
            cf.SetStringProperty(XMSC.WMQ_CHANNEL, _mqConfiguration.Channel);
            cf.SetStringProperty(XMSC.WMQ_QUEUE_MANAGER, _mqConfiguration.QueueManager);
            cf.SetStringProperty(XMSC.WMQ_SSL_CLIENT_CERT_LABEL, _mqConfiguration.CertificateLabel);
            cf.SetStringProperty(XMSC.WMQ_SSL_KEY_REPOSITORY, _mqConfiguration.KeyRepository);
            cf.SetStringProperty(XMSC.WMQ_SSL_CIPHER_SPEC, _mqConfiguration.CipherSuite);

            cf.SetIntProperty(XMSC.WMQ_CONNECTION_MODE, XMSC.WMQ_CM_CLIENT);
            cf.SetIntProperty(XMSC.WMQ_CLIENT_RECONNECT_OPTIONS, XMSC.WMQ_CLIENT_RECONNECT);
            cf.SetIntProperty(XMSC.WMQ_CLIENT_RECONNECT_TIMEOUT, XMSC.WMQ_CLIENT_RECONNECT_TIMEOUT_DEFAULT);
        }
        
        public IEnumerable<IMessage> ReceiveMessage()
        {
            using var connection = _connectionFactory.CreateConnection();
            using var session = connection.CreateSession(false, AcknowledgeMode.AutoAcknowledge);
            using var destination = session.CreateQueue(_mqConfiguration.ReceiveQueue);
            using var consumer = session.CreateConsumer(destination);

            connection.Start();

            var result = new List<IMessage>();
            var keepRunning = true;
            while (keepRunning)
            {
                try
                {
                    var sw = new Stopwatch();
                    sw.Start();

                    var message = _mqConfiguration.ConsumerTimeoutMs == 0 ? consumer.Receive() 
                        : consumer.Receive(_mqConfiguration.ConsumerTimeoutMs);

                    if (message != null)
                    {
                        result.Add(message);
                        _messageLogger.LogInMessage(message);
                        var ellapsedMillis = sw.ElapsedMilliseconds;
                        if (_mqConfiguration.ConsumerTimeoutMs == 0)
                        {
                            keepRunning = false;
                        }
                    }
                    else
                    {
                        keepRunning = false;
                    }
                }
                catch (Exception e)
                {
                    // We log the exception
                    keepRunning = false;
                }
            }

            consumer.Close();
            destination.Dispose();
            session.Dispose();
            connection.Close();

            return result;
        }

Solution

  • The symptoms look like a match for APAR IJ20591: Managed .NET SSL application making MQGET calls unexpectedly receives MQRC_CONNECTION_BROKEN when running in .NET Core. This impacts messages larger than 15kb and IBM MQ .net standard (core) libraries using TLS channels. See also this thread. This will be fixed in 9.2.0.5, no CDS release is listed.

    It states:

    Setting the heartbeat interval to lower values may reduce the frequency of occurrence.

    If your .NET application is not using a CCDT you can lower the heartbeat by having the SVRCONN channel's HBINT lowered and reconnecting your application.