I'm attempting to get MQ v6 to segment messages using the message flag MQMF_SEGMENTATION_ALLOWED and the put message option MQPMO_LOGICAL_ORDER as suggested in IBM's help guide.
ImqMessage message;
message.setFormat(MQFMT_STRING);
message.setMessageFlags(MQMF_LAST_MSG_IN_GROUP | MQMF_SEGMENTATION_ALLOWED);
/* ... */
ImqPutMessageOptions pmopts;
pmopts.setOptions(MQPMO_LOGICAL_ORDER);
if (!queue.put(message, pmopts))
{
buflen;
m_iLastError = queue.reasonCode();
CString reason;
reason.Format(_T("%d"), queue.reasonCode());
_errorMsg = "Reason code: " + reason;
/* throw exception etc.. */
}
Regardless whether I specify these flags, when I call put(), it always returns a false and has the reason code (2010) MQRC_DATA_LENGTH_ERROR.
Are there any common gotchas associated with v6 and segmentation (such as it not being available on Windows, anything glaring like that...), or any suggestions of things to try?
Apologies for the slightly context-free code sample btw. I'll try and answer questions that people have about my issue as best I can.
Okay, I found the solution to that particular error: A message that is larger than the channel's max message length will not be placed on the queue regardless of whether the message can be segmented or the max message sizes allowed by the queue and queue manager.
Setting the channel's max message size cannot be solely done by calling ImqChannel::maximumMessageLength()
. There's a config change required via the command line:
Enter runmqsc YOUR_QUEUE_MANAGER_NAME
In the prompt, check the existing channel's max message length (in v6, the default is 4MB):
display channel(CHANNEL_NAME)
You'll get something like
CHANNEL(SYSTEM.DEF.SVRCONN) CHLTYPE(SVRCONN)
ALTDATE(2013-07-12) ALTTIME(09.57.15)
COMPHDR(NONE) COMPMSG(NONE)
DESCR( ) HBINT(300)
KAINT(AUTO) MAXMSGL(4194304) <- max length, obvs ;-)
MCAUSER( ) MONCHL(QMGR)
RCVDATA( ) RCVEXIT( )
SCYDATA( ) SCYEXIT( )
SENDDATA( ) SENDEXIT( )
SSLCAUTH(REQUIRED) SSLCIPH( )
SSLPEER( ) TRPTYPE(TCP)
To increase the size:
alter channel(CHANNEL_NAME) CHLTYPE(SVRCONN) MAXMSGL(104857600)
for 100MB
Now you need to set the channel's value in code as well using ImqChannel::maximumMessageLength(104857600)
or it'll use the default of 4MB. MAXMSGL will take precedence over this call, so passing a value > MAXMSGL will have no effect.
Now, when you call put()
, any message without segmentation will cause the error 2030 (MQRC_MSG_TOO_BIG_FOR_Q) or 2031 (MQRC_MSG_TOO_BIG_FOR_Q_MGR). With segmentation, the message should now be split and the segments placed on the queue.
Hope this helps someone!