|
RSS Feed - WebSphere MQ Support
|
RSS Feed - Message Broker Support
|
Message under cursor |
« View previous topic :: View next topic » |
Author |
Message
|
RogerLacroix |
Posted: Fri Jul 30, 2004 8:39 am Post subject: Message under cursor |
|
|
 Jedi Knight
Joined: 15 May 2001 Posts: 3264 Location: London, ON Canada
|
All,
I was doing some testing of MQ code and have a question.
First the testing:
Test #1: I created a program to browse messages until a particular message then do a destructive get of it. I put 10 messages in the queue and had the program destructively get message number 6. This worked fine and the queue had 9 messages left the original message # 6 was removed.
I cleared the queue before the next test.
Test #2: I created a program to browse to message a particular message then do a destructive get of it and all remaining messages. I put 10 messages in the queue and had the program destructively get message number 6 and the remaining messages (7,8,9&10). This worked and but I did not get the results I was expecting. It should have removed the 5 messages starting at messages # 6 (i.e. 6,7,8,9&10). It removed 5 messages but they were message # 6,1,2,3&4. The message # 5,7,8,9&10 were left on the queue.
I did several tests and concluded the following: When the program does a destructive get for a 'message under cursor', it does not actually move the destructive get cursor.
For those who do not know, when an application reads a message there are 2 cursors that keep track of where you are while getting messages. There is a Browse Cursor and a Destructive Read Cursor. They are independent of each other.
I thought that when an application does a 'destructive get under cursor' (MQGMO_MSG_UNDER_CURSOR) that the destructive get cursor was moved to the current message position but that does not appear to be true. It remains at its previous position.
I.e. In my example, even though my app. did a 'destructive get under cursor' for message number 6, the destructive get cursor was still pointing to the first message in the queue.
So, to the question: How do you move the destructive get cursor without deleting messages? I have gone through the GetMessageOptions and I don't see anything.
It appears that once you starting browsing beyond the first message, you are stuck with doing the 'destructive get under cursor' for removing messages. (Because the 'destructive get under cursor' is still pointing at the first message. )
So, if this is not the solution, then what is a better one?
Regards,
Roger Lacroix _________________ Capitalware: Transforming tomorrow into today.
Connected to MQ!
Twitter |
|
Back to top |
|
 |
PeterPotkay |
Posted: Fri Jul 30, 2004 1:28 pm Post subject: |
|
|
 Poobah
Joined: 15 May 2001 Posts: 7722
|
Messages are 1 2 3 4 5 6 7 8 9 10.
You browse to message 6.
You get message 6 destructivly.
What do you get now if you do another browse? 7? Or 1?
Quote: |
For those who do not know, when an application reads a message there are 2 cursors that keep track of where you are while getting messages. There is a Browse Cursor and a Destructive Read Cursor. They are independent of each other.
|
Is this documented somewhere?
Quote: |
I thought that when an application does a 'destructive get under cursor' (MQGMO_MSG_UNDER_CURSOR) that the destructive get cursor was moved to the current message position but that does not appear to be true. It remains at its previous position.
|
The APR manual says:
Quote: |
Note that the browse cursor is not moved by nonbrowse MQGET calls using the same Hobj handle.
|
What does that mean???? I think it means: If you browse to #5, get #5, the cursor still points at #5? If yes, I would think you would then need to issue anothe MQGMO_BROWSE_NEXT, which would get you to #6, right? Or are you saying you get thrown to #1 no matter what?
What is your browse option on the next MQGET call after you succesfully pull #5? _________________ Peter Potkay
Keep Calm and MQ On |
|
Back to top |
|
 |
RogerLacroix |
Posted: Fri Jul 30, 2004 2:01 pm Post subject: |
|
|
 Jedi Knight
Joined: 15 May 2001 Posts: 3264 Location: London, ON Canada
|
Quote: |
Messages are 1 2 3 4 5 6 7 8 9 10.
You browse to message 6.
You get message 6 destructivly.
What do you get now if you do another browse? 7? Or 1? |
Browse will be # 7.
Quote: |
Quote: |
For those who do not know, when an application reads a message there are 2 cursors that keep track of where you are while getting messages. There is a Browse Cursor and a Destructive Read Cursor. They are independent of each other. |
Is this documented somewhere? |
Yes, I don't remember where it is.
Quote: |
The APR manual says:
Quote: |
Note that the browse cursor is not moved by nonbrowse MQGET calls using the same Hobj handle. |
|
Ah ha, per your previous item, this infers 2 cursors. (Otherwise, they want not have said 'browse' cursor.)
Quote: |
If you browse to #5, get #5, the cursor still points at #5? If yes, I would think you would then need to issue anothe MQGMO_BROWSE_NEXT, which would get you to #6, right? |
Yes. (Browsing).
But if I do a destructive get then I would get # 1.
Code: |
if (browse)
getOptions.options=MQC.MQGMO_BROWSE_NEXT+MQC.MQGMO_NO_WAIT+MQC.MQGMO_FAIL_IF_QUIESCING+MQC.MQGMO_ACCEPT_TRUNCATED_MSG;
else
getOptions.options=MQC.MQGMO_NO_WAIT+MQC.MQGMO_FAIL_IF_QUIESCING+MQC.MQGMO_ACCEPT_TRUNCATED_MSG; |
Now going back to your question, after I pull message #5 (get message under cursor), if the browse flag is true then message # 6 will be returned. But if the browse flag is false then message # 1 is returned.
Regards,
Roger Lacroix _________________ Capitalware: Transforming tomorrow into today.
Connected to MQ!
Twitter |
|
Back to top |
|
 |
PeterPotkay |
Posted: Fri Jul 30, 2004 2:08 pm Post subject: |
|
|
 Poobah
Joined: 15 May 2001 Posts: 7722
|
Browse to 5
GET 5
Browse next (will get you to 6?) <<<add this step to your process
GET 6
Browse next
GET 7
Will this work? _________________ Peter Potkay
Keep Calm and MQ On |
|
Back to top |
|
 |
RogerLacroix |
Posted: Fri Jul 30, 2004 2:23 pm Post subject: |
|
|
 Jedi Knight
Joined: 15 May 2001 Posts: 3264 Location: London, ON Canada
|
Hi,
I assume by 'Browse' you mean: do a non-destructive get and by 'GET' you mean a destructive get? True?
Let me lay it out without a loop structure. Assume 10 messages in the queue.
Scenario #1:
Open Queue
Browse First - returns #1
Browse Next - returns #2
Browse Next - returns #3
Browse Next - returns #4
Browse Next - returns #5
Browse Next - returns #6
Destructive Get message under cursor - - returns #6
Browse Next - returns #7
Browse Next - returns #8
Browse Next - returns #9
Browse Next - returns #10
Browse Next - returns 2033 - no more messages
Close Queue
Scenario #2:
Open Queue
Browse First - returns #1
Browse Next - returns #2
Browse Next - returns #3
Browse Next - returns #4
Browse Next - returns #5
Browse Next - returns #6
Destructive Get message under cursor - - returns #6
Destructive Get - returns #1
Destructive Get - returns #2
Destructive Get - returns #3
Destructive Get - returns #4
Destructive Get - returns #5
Destructive Get - returns 6th message in queue originally #7
Destructive Get - returns 7th message in queue originally #8
Destructive Get - returns 8th message in queue originally #9
Destructive Get - returns 9th message in queue originally #10
Destructive Get - returns 2033 - no more messages
Close Queue
If I don't stop it after a paricular number of messages then the above happens (i.e. only destructively get 5 messages).
Regards,
Roger Lacroix _________________ Capitalware: Transforming tomorrow into today.
Connected to MQ!
Twitter |
|
Back to top |
|
 |
PeterPotkay |
Posted: Fri Jul 30, 2004 2:27 pm Post subject: |
|
|
 Poobah
Joined: 15 May 2001 Posts: 7722
|
Try Scenario #3:
Open Queue
Browse First - returns #1
Browse Next - returns #2
Browse Next - returns #3
Browse Next - returns #4
Browse Next - returns #5
Browse Next - returns #6
Destructive Get message under cursor - - returns #6
Browse Next - returns #7
Destructive Get - returns #7
Browse Next - returns #8
Destructive Get - returns #8
Browse Next - returns #9
Destructive Get - returns #9
Browse Next - returns #10
Destructive Get - returns #10
Browse Next - returns 2033 - no more messages _________________ Peter Potkay
Keep Calm and MQ On |
|
Back to top |
|
 |
RogerLacroix |
Posted: Fri Jul 30, 2004 2:43 pm Post subject: |
|
|
 Jedi Knight
Joined: 15 May 2001 Posts: 3264 Location: London, ON Canada
|
Be right back ..........................
I'm Back.
For a minute, you had me wondering but here are the results:
Try Scenario #3:
Open Queue
Browse First - returns #1
Browse Next - returns #2
Browse Next - returns #3
Browse Next - returns #4
Browse Next - returns #5
Browse Next - returns #6
Destructive Get message under cursor - - returns #6
Browse Next - returns #7
Destructive Get - returns #1
Browse Next - returns #8
Destructive Get - returns #2
Browse Next - returns #9
Destructive Get - returns #3
Browse Next - returns #10
Destructive Get - returns #4
Browse Next - returns 2033 - no more messages
It's kinda cool that the cursors are truly independent of one another but it lends me back to my original question: How do you move the destructive get cursor?
Regards,
Roger Lacroix _________________ Capitalware: Transforming tomorrow into today.
Connected to MQ!
Twitter |
|
Back to top |
|
 |
PeterPotkay |
Posted: Fri Jul 30, 2004 4:25 pm Post subject: |
|
|
 Poobah
Joined: 15 May 2001 Posts: 7722
|
Quote: |
Browse Next - returns #6
Destructive Get message under cursor - - returns #6
|
but
Quote: |
Browse Next - returns #7
|
then
Quote: |
Destructive Get - returns #1
|
You got me Roger. The behaviour you are seeing is not what I would have expected. _________________ Peter Potkay
Keep Calm and MQ On |
|
Back to top |
|
 |
RogerLacroix |
Posted: Fri Jul 30, 2004 5:59 pm Post subject: |
|
|
 Jedi Knight
Joined: 15 May 2001 Posts: 3264 Location: London, ON Canada
|
Hi,
Actually, now that I have had a chance to think about it, it makes perfect sense. I would have expected it to work that way.
I was just re-reading sections in the APR manual and I can't seem to find anything about moving the destructive get cursor, other than doing a destructive get.
So to 'cherry pick' messages, I guess I'll have to browse and only use 'get under cursor' method.
Regards,
Roger Lacroix _________________ Capitalware: Transforming tomorrow into today.
Connected to MQ!
Twitter |
|
Back to top |
|
 |
PeterPotkay |
Posted: Sat Jul 31, 2004 3:36 am Post subject: |
|
|
 Poobah
Joined: 15 May 2001 Posts: 7722
|
Are you trying to allow a user of a GUI tool to CTRL + SHIFT and select multiple messages from a view, and then select DELETE, so that they can pick and choose messages from a queue to delete?
I think the only way to pull this off is that your program will have to generate its own index, record which messages the user selects, and then do an individual browse then destructive get of each one, all the while keeping the internal index in order. (The user selects Message #2 and #4 and #9 to delete:You have to browse 2 deep and destructive GET, then browse 2 deep again, and destructive GET, and finally browse 7 deep and destructive MQGET.)
If messages are deleted from the queue via Expiry or because another app read some, it will make the whole process much trickier and might cause the wrong message to be deleted if you're not careful in the design/testing. _________________ Peter Potkay
Keep Calm and MQ On |
|
Back to top |
|
 |
RogerLacroix |
Posted: Sat Jul 31, 2004 7:53 am Post subject: |
|
|
 Jedi Knight
Joined: 15 May 2001 Posts: 3264 Location: London, ON Canada
|
Hi,
Actually, for MQ Visual Edit, it uses 'Get by MsgId & CorrelId' for messages that the user wants to delete. Far more efficient.
What you described won't work unless you meant 'Destructive Get under Cursor' rather than just 'Destructive Get'. Because of my answer with scenario # 3.
I am building a non-GUI tool like MQ Visual Edit. I want to provide the ablility to delete messages 101-105 of a queue with 200 messages. I totally agree that expired messages may skew the numbering of messages in a queue. But it is up to the user to understand the messages in their queues. (That may be a pipe dream - but almost every tool can be dangerous if you don't understand it or the data.)
Regards,
Roger Lacroix _________________ Capitalware: Transforming tomorrow into today.
Connected to MQ!
Twitter |
|
Back to top |
|
 |
PeterPotkay |
Posted: Sat Jul 31, 2004 11:25 am Post subject: |
|
|
 Poobah
Joined: 15 May 2001 Posts: 7722
|
Quote: |
Actually, for MQ Visual Edit, it uses 'Get by MsgId & CorrelId' for messages that the user wants to delete. Far more efficient.
|
But technically it is vulnerable to the scenario where developers dumps messages to the queue with all the same Message-ID and maybe no Correl-ID, or the same Correl-ID. Yeah, I seen it happen and it foiled a GUI tool that relied on MessageID+CorrelID+PutTime for the selection of deleting a specific message off of a queue. The developers were dumping the messages with the same IDs to the queue so fast that some of the messages had the same PutTime.
Then the users were trying to copy a specific message to put to another q or to delete it, and invariably getting the wrong one.
You and I both know they shouldn't have put the messages to the queue with the same IDs. But man did we waste a lot of time trying to figure out the confusion when they thought they were getting a particular message with particular data and they weren't getting the results they were supposed to. (They did fix their code to allow unique MessageIDs.)
If by MessageID / CorrelID is how your tool grabs the messages, I would put a warning in the documenttion (if its not already there) saying results will not be as expected if the messages are sitting on the queues with identical IDs. _________________ Peter Potkay
Keep Calm and MQ On |
|
Back to top |
|
 |
jefflowrey |
Posted: Sat Jul 31, 2004 1:27 pm Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
Yeah - I seem to remember warning Roger, a while ago, about a similar problem encountered with QPasa.
Message ID + Correlation ID = not guaranteed unique. Sorry Roger!  _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
RogerLacroix |
Posted: Sat Jul 31, 2004 6:08 pm Post subject: |
|
|
 Jedi Knight
Joined: 15 May 2001 Posts: 3264 Location: London, ON Canada
|
Oops, I shouldn't have brought up MQ Visual Edit cause now we have changed subjects. Peter, yes, I agree with you and MQ Visual Edit's docs states that things like deletion, forwarding, etc... are done by MsgID + CorrelID. It is a restriction and every once in a while I get an email about it.
Jeff, I kind of remember a discussion (But I've never used QPasa).
Please let me refocus this thread back to the question: How do you move the destructive get cursor?
Regards,
Roger Lacroix _________________ Capitalware: Transforming tomorrow into today.
Connected to MQ!
Twitter |
|
Back to top |
|
 |
gunter |
Posted: Sun Aug 01, 2004 4:56 am Post subject: |
|
|
Partisan
Joined: 21 Jan 2004 Posts: 307 Location: Germany, Frankfurt
|
Roger,
I made a quick test on this by changing the code in amqsget. I couldn't find any unexpected behavior.
The result is:
$ ./brouwse_under_cursor TT QM1
Sample AMQSGET0 start
Browse Next <#1> // it's first
Browse Next <#2>
Browse Next <#3>
Browse Next <#4>
Browse Next <#5>
Browse Next <#6>
Destructive Get <#6>
Browse Next <#7>
Destructive Get <#7>
Browse Next <#8>
Destructive Get <#8>
Browse Next <#9>
Browse Next <#10>
After this the content of the queue is:
$ ./amqsget TT QM1
Sample AMQSGET0 start
message <#1>
message <#2>
message <#3>
message <#4>
message <#5>
message <#9>
message <#10>
no more messages
Here the code I changed:
Code: |
gmo.Options = MQGMO_WAIT /* wait for new messages */
+ MQGMO_BROWSE_FIRST
+ MQGMO_CONVERT; /* convert if necessary */
gmo.WaitInterval = 15000; /* 15 second limit for waiting */
while (CompCode != MQCC_FAILED)
{
buflen = sizeof(buffer) - 1; /* buffer size available for GET */
memcpy(md.MsgId, MQMI_NONE, sizeof(md.MsgId));
memcpy(md.CorrelId, MQCI_NONE, sizeof(md.CorrelId));
md.Encoding = MQENC_NATIVE;
md.CodedCharSetId = MQCCSI_Q_MGR;
MQGET(Hcon, /* connection handle */
Hobj, /* object handle */
&md, /* message descriptor */
&gmo, /* get message options */
buflen, /* buffer length */
buffer, /* message buffer */
&messlen, /* message length */
&CompCode, /* completion code */
&Reason); /* reason code */
if (CompCode != MQCC_FAILED)
{
buffer[messlen] = '\0'; /* add terminator */
printf("Browse Next <%s>\n", buffer);
i++;
if( i > 5 && i < 9 )
{
memcpy(md.MsgId, MQMI_NONE, sizeof(md.MsgId));
memcpy(md.CorrelId, MQCI_NONE, sizeof(md.CorrelId));
md.Encoding = MQENC_NATIVE;
md.CodedCharSetId = MQCCSI_Q_MGR;
gmo.Options = MQGMO_WAIT /* wait for new messages */
+ MQGMO_MSG_UNDER_CURSOR
+ MQGMO_CONVERT; /* convert if necessary */
MQGET(Hcon, /* connection handle */
Hobj, /* object handle */
&md, /* message descriptor */
&gmo, /* get message options */
buflen, /* buffer length */
buffer, /* message buffer */
&messlen, /* message length */
&CompCode, /* completion code */
&Reason); /* reason code */
printf("Destructive Get <%s>\n", buffer);
}
}
gmo.Options = MQGMO_WAIT /* wait for new messages */
+ MQGMO_BROWSE_NEXT
+ MQGMO_CONVERT; /* convert if necessary */
}
|
_________________ Gunter Jeschawitz
IBM Certified System Administrator - Websphere MQ, 5.3 |
|
Back to top |
|
 |
|
|
 |
Goto page 1, 2 Next |
Page 1 of 2 |
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|
|
|