Starter Kit- Chapter 30 System iNetwork (formerly iSeries Network)
Home Site Map Contact Us My Profile Log In Join Now!
Info Centers
 Forums

 Tech Center

 News & Analysis

 Solution Center

 UK Centre
Popular Spots
 25th Anniversary

 Article Archive

 ProVIP Center (Club Tech)

 Code

 System i DocFinder

 Essential Guides

 Blogs

 Wikis

 e-Learning

 Webcasts

 Podcasts

 System i Jobs

 Events
Products
 i5 Route Finders

 Learning Center (Store)

 Product Directory
Network Poll
Determining a programmer's desktop requirements is not a black-and-white proposition, but matching equipment to programmer type can help productivity. Which "programmer type" are you?
Vote Now!
Network Memberships
 See Membership Levels

 Free E-Mail Newsletters

 Free RSS Feeds

 Subscribe/Join

 Upgrade Now

 Renew Now
About Us
 About the Network

 Network Publications

 Tech Editor Profiles

 Editorial Calendar

 Contact Us

 Subscribe

 Media Kit (PDF)

 Write For Us


System iNetwork November Sponsor





        System iNetwork November Sponsor


Home » Starter Kit » TOC » Chapter 30
  AS/400-iSeries Starter Kit


Chapter 30 - Just Between Us Programs

In Chapter 7, I explained that you can use the SNDMSG (Send Message), SNDBRKMSG (Send Break Message), or SNDNETMSG (Send Network Message) command to communicate with someone else on your AS/400. In Chapter 29, I showed how to use one of these commands or the SNDUSRMSG (Send User Message) command to have a program send a message to a user. But when you want to establish communications between programs, none of these commands will do the job; you need the SNDPGMMSG (Send Program Message) and RCVMSG (Receive Message) commands.

Now I want to introduce the SNDPGMMSG command (see Chapter 31 for a discussion of the RCVMSG command). Program messages are normally used for one of two reasons: to send error messages to the calling program (so it knows when a function has not been completed) or to communicate the status or successful completion of a process to the calling program. In this chapter, you'll learn how a job stores messages, how to have one program send a message to another, what types of messages a program can send, and what actions they can require a job to perform. But first, you need to understand the importance of job message queues.

Job Message Queues

All messages on the AS/400 must be sent to and received from a message queue. User-to-user and program-to-user messages are exchanged primarily via nonprogram message queues (i.e., either a workstation or a user message queue). OS/400 creates a nonprogram message queue when a workstation device or a user profile is created. You can also use the CRTMSGQ (Create Message Queue) command to create nonprogram message queues. For example, you might want to create a message queue for communication between programs that aren't part of the same job. Or you might want to create a central message queue to handle all print messages. Both users and programs can send messages to and receive them from nonprogram message queues.

Although programs can use nonprogram message queues to communicate to other programs, OS/400 provides a more convenient means of communication between programs in the same job. For each job on the system, OS/400 automatically creates a job message queue that consists of an external message queue (*EXT, through which a program communicates with the job's user) and a program message queue (for each program invocation in that job).

Figure 30.1 illustrates a sample job message queue. OS/400 creates an external message queue when a job is initialized and deletes the queue when the job ends. OS/400 also creates a program message queue when a program is invoked and deletes it when the program ends (before removing the program from the job invocation stack). The job message queue becomes the basis for the job log produced when a job is completed. The job log includes all messages from the job message queue, as well as other essential job information. (For more information about job logs, see "Understanding Job Logs".)




The SNDPGMMSG Command

Figure 30.2 shows the parameters associated with the SNDPGMMSG command prior to OS/400 V2R3. Because of the introduction of ILE (Integrated Language Environment) support in OS/400 V2R3, the SNDPGMMSG command now includes some additional parameter elements that address specific ILE requirements (see the section "ILE-Induced Changes"). You can use the SNDPGMMSG command in a CL program to send a program message to a nonprogram or program message queue. You can enter an impromptu message (up to 512 characters long) on the MSG parameter, or you can use the MSGID, MSGF, and MSGDTA parameters to send a predefined message. (To review predefined messages, see Chapter 29, "Teaching Programs to Talk.")

The TOPGMQ parameter is unique to the SNDPGMMSG command and identifies the program queue to which a message will be sent. TOPGMQ consists of two values: relationship and program. The first value specifies the relationship between the target program and the sending program. For this value, you can specify *PRV (indicating the message is to go to the target program's caller or requester), *SAME (the message is to be sent to the target program itself), or *EXT (the message is to go to the target job's external message queue). The second value specifies the target program and can be either the name of a program within the sending program's job or the special value *, which tells OS/400 to use the sending program's name.

The default value for the TOMSGQ parameter, *TOPGMQ, tells the system to refer to the TOPMGQ parameter to determine the destination of the message.

Let's look at the job message queues shown in Figure 30.1. Assuming that PGM_D is the active program, let's suppose PGM_D executes the following SNDPGMMSG command:

SNDPGMMSG MSG('Test message')                 +
          TOMSGQ(*SYSOPR) MSGTYPE(*INFO)

PGM_D would send the message "Test message" to the system operator's workstation message queue because the value *SYSOPR was specified for the TOMSGQ parameter. In the following SNDPGMMSG command,

SNDPGMMSG MSG('Test message') TOMSGQ(*TOPGMQ) +
          TOPGMQ(*SAME *) MSGTYPE(*INFO)

the parameter TOMSGQ(*TOPGMQ) tells OS/400 to use the TOPGMQ parameter to determine the message destination. Because TOPGMQ specifies *SAME for the relationship and * for the target program, the system sends the message "Test message" to program message queue PGM_D. Now consider the command

    SNDPGMMSG MSG('Test message')            +
               TOPGMQ(*PRV *) MSGTYPE(*INFO)

In this case, the message is sent to program message queue PGM_C, because PGM_C is PGM_D's calling program (*PRV). (Notice that this time I chose not to specify the TOMSGQ parameter, but to let it default to *TOPGMQ.)

As on the SNDUSRMSG command, SNDPGMMSG's TOUSR parameter lets your program send a message to a particular user profile. You can specify *ALLACT for the TOUSR parameter to send a message to each active user's message queue. Although this value provides an easy way for a program to send a message to all active users, it does not guarantee that users immediately see the message. Each user message queue processes the message based on the DLVRY attribute specified for the message queue.

ILE-Induced Changes

In OS/400 V2R3, the SNDPGMMSG TOPGMQ parameter is expanded to include ILE (Integrated Language Environment) support. Figure 30.3 presents the new TOPGMQ parameter structure, which contains two elements. The first element, "relationship," works just the same as in V2R2. The second element is now called "Call stack entry identifier" and is expanded to multiple fields that help identify the exact program message queue to receive the message. The first entry field is the "Call stack entry" field and is similar to the V2R2 implementation. This field represents the name of the program or procedure message queue. If this entry is a procedure name, the name can be a maximum of 256 characters. The system will begin searching for this procedure in the most recently called program or procedure. If more qualifications are needed to correctly identify the procedure message queue, you can use the next two items, "Module name" and "Bound program name," to specifically point to the exact procedure message queue. The module identifies the module into which the procedure was compiled. The bound program name identifies the program name into which this procedure was bound.




Note that, when using the new SNDPGMMSG command, it is in this third item that you can enter the single value "*EXT" to tell OS/400 to send the message to the external message queue of the current job. Prior to V2R3, you entered this special value in the "relationship" parameter element of the SNDPGMMSG command.

Message Types

The next parameter on the SNDPGMMSG command is MSGTYPE. You can use six types of messages in addition to the informational and inquiry message types that you can create with the SNDMSG and SNDUSRMSG commands. Figure 30.4 lists the message types and describes the limitations (message content and destination) and normal uses of each. Each message type has a distinct purpose and communicates specific kinds of information to other programs or to the job's user.

You can send an informational message (*INFO) to any user, workstation, or program message queue. Because inquiry messages (*INQ) expect a reply, you can send an inquiry message only to a nonprogram message queue (i.e., a user or workstation message queue) or to the current job's external message queue.

A completion message (*COMP) is usually sent to inform the calling program that the requested work is complete. It can be sent to a program message queue or to the job's external message queue.

Diagnostic messages (*DIAG) are sent to program or external message queues to describe errors detected during program execution. Typically, escape messages follow diagnostic messages, telling the calling program that diagnostic messages are present and that the requested function has failed.

You can send a request message (*RQS) to any message queue as a command request. You must use an impromptu message on the MSG parameter to send the request. (For more information about request messages and request message processing, see Chapter 8 of the Control Language Programmer's Guide, SC41-8077).

An escape message (*ESCAPE) specifically identifies the error that caused the sending program to fail. An escape message can be sent only to a program message queue, and the escape message terminates the sending program, returning control to the calling program. MSGTYPE(*ESCAPE) cannot be specified if the MSG parameter is specified -- in other words, all escape messages must be predefined.

Status messages (*STATUS) describe the status of the work that the sending program performs. When a program sends a status message to an interactive job's external message queue, the message is displayed on the workstation screen, processing continues, and the sending program does not require a response. When a status message is sent to a program message queue, the message functions as a warning message. If the program receiving the message monitors for this message (using the MONMSG (Monitor Message) command, which I will discuss in Chapter 31, the message functions as an escape message by terminating the sending program. If the program receiving the status message does not monitor for that message, the system immediately returns control to the sending program.

OS/400 uses notify messages (*NOTIFY) to describe a condition in the sending program that requires a correction or a reply. If the notify message is sent to an interactive job's external message queue, the message acts like an inquiry message and waits for a reply, which the sending program can then receive. When a notify message is sent to a program message queue, the message functions as a warning.

If the program receiving the notify message monitors for it, the message causes the sending program to end, and control returns to the receiving program. If the receiving program doesn't monitor for the message, or if the message is sent to a batch job's external message queue, the default reply for that message is sent, and control returns to the sending program. You can either define the default reply in the message description or specify it on the system reply list.

The Receiving End

The next parameter on the SNDPGMMSG command is RPYMSGQ, which lets you specify the program or nonprogram message queue to which the reply should go. The only valid values are *PGMQ, which specifies that the reply is to go to the sending program's message queue, or a qualified nonprogram message queue name.

You can receive or remove a specific message by using a key value to identify that message. The KEYVAR parameter specifies the CL return variable containing the message key value of the message sent by the SNDPGMMSG command. To understand how key variables work, examine the following CL statement:

SNDPGMMSG MSG('Test message')            +
          TOPGMQ(*PRV *) MSGTYPE(*INFO)  +
          KEYVAR(&MSGKEY)

The SNDPGMMSG command places the message on the calling program's message queue, and OS/400 assigns to that message a unique message identifier that is returned in the &MSGKEY variable. In the example

RMVMSG PGMQ(*PRV *)  +
       MSGKEY(&MSGKEY) CLEAR(*BYKEY)

the RMVMSG (Remove Message) command uses the &MSG KEY value to remove the correct message from the queue. The return variable must be defined as TYPE(*CHAR) and LEN(4).

Program Message Uses

Now that you're acquainted with SNDPGMMSG parameters, let's look at a few examples that demonstrate how to use this command. The following is a sample diagnostic message:

SNDPGMMSG MSGID(CPF9898)            +
          MSGF(QSYS/QCPFMSG)        +
          MSGDTA('Output queue' |>  +
                 &outqlib       |<  +
                 '/'            ||  +
                 &outq          |>  +
                 'not found')       +
          TOPGMQ(*PRV) MSGTYPE(*DIAG)

In this example, I have concatenated constants (e.g., output queue and /) and two variables (&outqlib and &outq) to construct the diagnostic message "Output queue &outqlib/&outq not found." The current program sends this message to the calling program, which can receive it from the program message queue after control returns to the calling program.

As I mentioned in my discussion of the MSGTYPE parameter, you must supply a valid message ID for the MSGID keyword when you send certain message types (to review which types require a message ID, see Figure 30.3). Because this means you cannot simply use the MSG parameter to construct text for these message types, OS/400 provides a special message ID, CPF9898, to handle this particular requirement. The message text for CPF9898 -- &1. -- means that substitution variable &1 will supply the message text, which you can construct using the MSGDTA parameter.

Notice that the message text in the preceding example is constructed in the MSGDTA parameter. When the program sends the message, the MSGDTA text becomes the message through substitution into the &1 data variable. (For a more complete explanation of message variables, see Chapter 29, "Teaching Programs to Talk;" the Programming: Control Language Reference, SC41-0030; and the Programming: Control Language Programmer's Guide, SC41-8077.)

The next example is an escape message that might follow such a diagnostic message:

SNDPGMMSG MSGID(CPF9898)                           +
          MSGF(QCPFMSG)                            +
          MSGDTA('Operations ended in error.' |>   +
                 'See previously listed messages') +
          TOPGMQ(*PRV)                             +
          MSGTYPE(*ESCAPE)

OS/400 uses an escape message to terminate a program when it encounters an error. When a program sends an escape message, the sending program is immediately terminated, and control returns to the calling program.

In the following example, the current program sends a completion message to the calling program to confirm the successful completion of a task.

SNDPGMMSG MSGID(CPF9898)                              +
          MSGF(QCPFMSG)                               +
          MSGDTA('Copy of spooled files is complete') +
          TOPGMQ(*PRV)                                +
          MSGTYPE(*ESCAPE)

The following sample status message goes to the job's external message queue and tells the job's external user what progress the job is making.

SNDPGMMSG MSGID(CPF9898)                              + 
          MSGF(QCPFMSG)                               + 
          MSGDTA('Copy of spooled files in progress') + 
          TOPGMQ(*EXT)                                + 
          MSGTYPE(*STATUS)
When you send a status message to an interactive job's external message queue, OS/400 displays the message on the screen until another program message replaces it or until the message line on the display is cleared.

Although you may be ready to send messages to another program, you have only half the picture. In Chapter 31, you will learn how programs receive and manipulate messages, and I'll give you some sample code that contains helpful messaging techniques.


Starter Kit for the AS/400, 2nd Edition
Copyright 1994 by Duke Press
DUKE COMMUNICATIONS INTERNATIONAL
Loveland, Colorado

All rights reserved. No part of this book may be reproduced in any form by any electronic or mechanical means (including photocopying, recording, or information storage and retrieval) without permission in writing from the publisher.

It is the reader's responsibility to ensure procedures and techniques used from this book are accurate and appropriate for the user's installation. No warranty is implied or expressed.

This book was printed and bound in the United States of America.
Second Edition: April 1994

ISBN 10882419-09-X



  Sponsored Links   Featured Links


Penton Technology Media
Connected Home | SQL Server Magazine | Windows IT Pro
Report Bugs | Contact Us | Comments/Suggestions | Terms & Conditions | Privacy Policy | Trademarks
See Membership Levels | Subscribe | Free E-mail Newsletters | Free RSS Feeds | My Profile | Upgrade Now | Renew Now

Copyright © 2008 - Penton Technology Media
Penton Media
System i is a trademark of International Business Machines Corporation and is used by Penton Media, Inc., under license. SystemiNetwork.com is published independently of International Business Machines Corporation, which is not responsible in any way for the content. Penton Media, Inc., is solely responsible for the editorial content and control of the System iNetwork.