TPF MQSeries PUT 15 Enhancements (APAR PJ28136)
Trigger EVERY and MQGET with WAIT
Chin Hung and John Tarby, IBM TPF Development
Have you ever wanted to automatically start more instances (ECBs) of your application to process a queue when the message rate was gearing up during peak hours? What if you had a low-volume queue that was going to be serviced by a single ECB and you didn't want to start up a new process every time a message arrived? Now you can do these by using trigger EVERY and MQGMO_WAIT support, which are provided on PUT 15.
I thought that TPF already supported a trigger mechanism?
With the initial support for a local queue manager on TPF, we provided trigger FIRST support, which provides a user exit that is invoked when an MQGET request is attempted from an empty queue that subsequently has a message put on it. Trigger EVERY support on TPF allows a new instance of an application to be invoked every time a new message is put on the queue. The application to be invoked is identified by the process object associated with the queue. A new command, ZMQSC DEFINE PROCESS, creates process objects and contains the four-letter application dynamic load module (DLM) name, environment data, and user data. Trigger FIRST support is also updated if you want to invoke a program specified in the process object instead of the current trigger FIRST user exit program, CUIR.
What is the difference between MQSeries Trigger EVERY support on TPF and the one that is on other platforms?
In MQSeries trigger support on other platforms, when a message arrives on a queue, the queue manager generates a trigger message that is put on an initiation queue specified in the local queue definition. A user then needs to write and run a trigger monitor program to get the trigger message from the initiation queue and start the appropriate application program. If the trigger monitor is a single ECB processing the initiation queue, the trigger monitor can then become a bottleneck for processing an application queue.
This design does not apply really well in the TPF environment. TPF performs best when many ECBs concurrently process a queue. To avoid any bottlenecks that an initiation queue may introduce, we have implemented a fast-path trigger monitor. With our fast-path trigger EVERY monitor, whenever a message is put on a local queue, the fast-path trigger monitor will generate a trigger message (in MQTMC2 format), create a new ECB, and pass the trigger message to the application DLM specified in the process definition instantaneously (via the swisc_create function).
The Trigger Monitor
A trigger monitor is started automatically when the queue manager starts. Whenever a new message is put on a local queue that has trigger EVERY set and a process object defined, the queue manager increments the trigger counter (TriggerPendingCount) of that local queue by 1. The trigger monitor is an ECB-controlled program that examines the trigger counters of all local queues. If the trigger count of any one of the queues is greater than 0, it generates the trigger message and passes the message to the application DLM. For each queue, 10 application ECBs ( at most) are created at a time; a delayc function is then issued and the trigger monitor will continue on to the next queue. Delayc function calls are issued to avoid a system shutdown caused by the spawning of too many ECBs at one time when a large batch of messages arrives on a queue. The trigger monitor keeps looping through all the local queues until the trigger counts of all local queues are zeros. If all trigger counts are zeros, the trigger monitor will create an event and then issue an event wait (evnwc function) to wait for a message to be put on a queue. The MQPUT logic will issue a postc function if the trigger monitor issues an evnwc function.
Each instance of the trigger monitor runs for 5 seconds. Every 5 seconds, a new instance of the trigger monitor is created (via the swisc_create function) by the MQ Timer routine and the old instance of the trigger monitor is exited. With this implementation of the trigger monitor, there will be no interruption of the triggering service at any time when the queue manager is running. It also allows customers to load and activate a new loadset containing the trigger monitor because the new trigger monitor will be executed when the MQ Timer creates (via swisc_create) the new trigger monitor ECB.
OK, then what is the setup that I need to get Trigger EVERY running?
1. Write or modify your MQSeries application program to accept the trigger message (in MQTMC2 format) to process the message on the queue or pass control to another program.
2. Build and load your application DLM to TPF.
3. Define a process associated with this application:
ZMQSC DEF PROCESS-MYPROCESS APPLICID-appl ENVRDATA-MYENVR USERDATA-TESTING
4. Define or alter the queue definition that you want to have triggering on every message:
ZMQSC ALTER QL-TESTQ PROCESS-MYPROCESS TRIGGER TRIGTYPE-EVERY TRIGDATA-THISISTRIGGER
Now, on to MQGET with WAIT
With the trigger EVERY model, a new ECB is created for every message that arrives on the queue. Another application model is made possible with the introduction of support for the MQGMO_WAIT option on the MQGET API.
What does it do?
MQGET with the MQGMO_WAIT option set does just what the name implies. If there are no messages on the queue, you can then specify the WAIT option and MQSeries will suspend your ECB until either a message arrives or the time that you specified in the MQGMO WaitInterval field has lapsed. This flexibility allows applications to wait for a reasonable length of time for a message to arrive, but if it never shows up, the application is not left waiting indefinitely. Of course, if it does want to wait indefinitely, that option is available too; just set WaitInterval to MQWI_UNLIMITED. The only way that the application will get control back at that point is if a message arrives on the queue, the queue manager is stopped, or the queue is deleted.
How do I use it?
To use the WAIT option, an application needs to set the MQGMO_WAIT flag in the Options field of the MQGMO structure that is already passed on each MQGET call. It also needs to update the WaitInterval field to indicate, in milliseconds, how long the application should be suspended if there are no messages available when MQGET is issued.
Return to the Newsletter table of contents
|