Working with Data Queues in CL programs on IBM i

Hello everyone and welcome to this post about Data Queues objects on IBM i. This will be the first of a series of three posts about data queues. In this first post I will talk about how to work with data queues in CL Programs. In the second post I will use an ILE RPG program and finally in the third post I will use IBM i Services.

Data queues are one of the most efficient and elegant interprocess communication (IPC) mechanisms on IBM i. They provide a fast, flexible way to exchange messages between jobs or between different parts of the same application. While most developers use RPG or COBOL to interact with data queues, Control Language (CL) also provides native support to work with them—often overlooked but highly effective for system utilities, job orchestration, and messaging workflows.

In this post, we’ll take a deep dive into how to use data queues from CL programs. We’ll cover queue creation, sending and receiving messages, and best practices when integrating data queues into CL-based architectures.

What are Data Queues?

A data queue is an object of type *DTAQ that allows programs to enqueue and dequeue data records. Think of it as a high-performance FIFO (first-in, first-out) buffer managed by the system. Each entry in the queue can have a fixed or variable length, and can be processed asynchronously.

Data queues are especially valuable in:

  • Event-driven architectures
  • Job queues and schedulers
  • Cross-language communication (e.g., RPG ↔ CL, CL ↔ Java)
  • Real-time data processing

According to how entries can be retrieved data queues can be FIFO (First In First Out), LIFO (Last In First Out) or KEYED

The type of the data queue can be *STD (standard), *DDM (remote) or *DSP (to use with a display file).

Commands, APIs and IBM i Services.

In this section I will show which data queue operations can be performed with commands and APIs or IBM i Services. In this post I will only talk about commands and APIs. Stay tuned because part three of the series will be all about IBM i services.

Commands

As I’ve said before a data queue is an object of type *DTAQ so it can be created and deleted and this can only be done with commands and those, along with WRKDTAQ, are the only commands available for working with data queues.. All other operations are performed via APIs or IBM i services.

  • CRTDTAQ is used to create a data queue. It has several parameters and at least you must type the name of the data queue and in which library you want to store it and the maximum length of the entries. I will write an example below explaining the parameters used.
  • DLTDTAQ is used to delete a data queue. The name and the library of the data queue are required.
  • WRKDTAQ is used to create, delete or change the description of a data queue.

APIs

There are several APIs to work with data queues so you can perform operations other than create or delete a data queue. An API is a program that performs an operation and that has input and output parameters. IBM has a Web page called API Finder where you can search IBM i APIs by name, category and so on. You can visit the Web page clicking here. This Web page is a must if you are going to work with APIs. You will see which parameters the API has, which of them are input or output, the type and any other consideration to use the API.

I will list all the data queues APIs and a brief description of what each one does and I will explain some of them deeper in the examples.

  • QSNDDTAQ is used to send a message to the data queue.
  • QRCVDTAQ is used to receive the next message from the data queue or the one that match the key specification on a keyed data queue. The entry can only be received by one program and it will be removed from the data queue after it has been received.
  • QMHRDQM is used to receive one or more messages from the data queue. The entry remains in the data queue after it has been read.
  • QCLRDTAQ is used to clear all the messages from the data queue or the ones that match the key specification on a keyed data queue.
  • QMHQCDQ is used to change the data queue. Only Automatic reclaim  and Enforce data queue locks attributes can be changed.
  • QMHQRDQD is used to retrieve the description and attribute values of the data queue. There are two formats with different information available so use the API finder to view how to use it.

CL Program Example

It is now time to go through a complete example using Control Language.

Management ask for a program that prints orders once they are completed. To accomplish this task IT department is going to develop two programs. The first program will send the order number to a data queue once it is completed and continues with other things or processing more orders. The second program, asynchronously, will read the order number from the data queue and call a program passing the order number as a parameter and print the order. This second program will run in batch and wait forever for an order to arrive. To end this second program the first one must send a “flag” that causes the second program to finish.

To keep things simple in the example, the first program will have a screen where you can type an order number and the flag to end the second program.

Creating the Data Queue

First of all a data queue is needed to store the order numbers in the same sequence they have been processed. The command to create this data queue is:

CRTDTAQ DTAQ(*CURLIB/ORDERNUM) TYPE(*STD) MAXLEN(5) SEQ(*FIFO) SIZE(*MAX16MB 1) AUTORCL(*YES) TEXT('Order numbers to print')

This command will create the ORDERNUM data queue in the current library. The type is standard which means is local. The maximum length of an entry is five characters. The entries are retrieved in the same order as they have been sent. The maximum size of the data queue will be 16 MB and it will have 1 initial entry so its initial size will be 5 bytes. Auto reclaim is set to *YES so the storage allocated for the data queue is automatically reclaimed when the data queue is empty and it will have the initial number of entries again, one in this case.

Display File SNDDTAQD

This simple screen file is used to send order numbers to the data queue. You can see the code below. I am not going to explain the entire screen file I will just list all the components that will be used in the CL program.

SNDDTAQD:

				
					     A                                      CA03(03)
     A                                      CA06(06)
     A          R SNDORDNUM
     A                                  1  2SYSNAME
     A                                  1 33'Send Order Number'
     A                                      DSPATR(UL)
     A                                      COLOR(RED)
     A                                  1 70DATE(*YY)
     A                                      EDTCDE(Y)
     A            PGMNAM        10   O  2  2
     A                                  2 72TIME
     A                                  7  6'Order number. . . :'
     A            ORDNUM         5   I  7 26
     A            MESSAGE       66   O 12  9DSPATR(HI)
     A                                 23  2'F3=Exit'
     A                                      COLOR(BLU)
     A                                 23 11'F6=Send Flag and Exit'
     A                                      COLOR(BLU)
				
			

Things to consider:

Function Keys

  • F3
  • F6

Record Formats

  • SNDORDNUM

Variables

  • &IN03
  • &IN06
  • &PGMNAM
  • &ORDNUM
  • &MESSAGE

CL Program #1 – SNDDTAQC

Program SNDDTAQC will use the screen SNDDTAQD to get the order number to send to the data queue. There will be another program called RCVDTAQC that will be used to retrieve the order number from the data queue and process it.

RCVDTAQC will wait for an order number to arrive in the data queue. If the user presses function key F3, SNDDTAQC will terminate, but RCVDTAQC will continue waiting for an order number because the termination flag is not sent with F3. If the user presses function key F6, SNDDTAQC will also terminate; however, before doing so, it will send the character string END to RCVDTAQC, which will interpret it as a termination flag and end its execution

SNDDTAQC:

				
					PGM
DCLF FILE(SNDDTAQD)
DCL VAR(&QNAME)    TYPE(*CHAR) LEN(10)  VALUE(ANTDTAQ)
DCL VAR(&QLIB)     TYPE(*CHAR) LEN(10)  VALUE(ANTDTAQLIB)
DCL VAR(&QDATALEN) TYPE(*DEC) LEN(5 0) VALUE(5)
DCL VAR(&QDATA)    TYPE(*CHAR) LEN(5)
SNDRCVF RCDFMT(SNDORDNUM)
DOWHILE (*NOT &IN03)
    IF &IN06 (DO)
        CHGVAR VAR(&QDATA) VALUE('END')
        CALL QSNDDTAQ (&QNAME &QLIB &QDATALEN &QDATA)
        RETURN
    ENDDO
    CHGVAR VAR(&QDATA) VALUE(&ORDNUM)   
    CALL QSNDDTAQ (&QNAME &QLIB &QDATALEN &QDATA)
    CHGVAR VAR(&MESSAGE) VALUE('Order number' *BCAT &ORDNUM *BCAT 'processed.')
    SNDRCVF RCDFMT(SNDORDNUM)
ENDDO
ENDPGM
				
			

Explanation:

Line 1: Program starts

Line 2: Declaration of the screen file SNDDTAQD.

Line 3: Name of the data queue. In this case ANTDTAQ.

Line 4: Library of the data queue. In this case ANTDTAQLIB.

Line 5: Length of the data to send to the data queue. Must be the same as the value specified in the MAXLEN parameter of the CRTDTAQ command.

Lines 6: Variable to hold the data to send to the data queue.

Note: These four variables correspond to the first four parameters of the QSNDDTAQ API which are mandatory.

Line 7: The screen is written and waiting for and order number or a function key.

Line 8: While F3 is not pressed…

Line 9 – 13: If F6 is pressed ‘END’ character string is assigned to &QDATA variable and sent to the data queue. Then SNDDTAQC program ends.

Line 14: The value of &ORDNUM from the screen file is assigned to &QDATA.

Line 15: The value of &QDATA is sent to the data queue.

Lines 16: A message with the order number processed is assigned to &MESSAGE screen field.

Line 17: The screen is written so the message can be viewed and it will wait for another order number or a function key.

Line 18: DOWHILE loop ends.

Line 19: Program ends.

CL Program #2 – RCVDTAQC

Program RCVDTAQC will run in batch mode, waiting indefinitely for an order to arrive. Once an order number is placed in the data queue, it will retrieve and process it, sending a message to the user running the program to confirm that the order has been processed. If the order number is the character string END—the termination flag—the program will end.

RCVDTAQC:

				
					PGM
DCL VAR(&QNAME)    TYPE(*CHAR) LEN(10)  VALUE(ORDERNUM)
DCL VAR(&QLIB)     TYPE(*CHAR) LEN(10)  VALUE(ASALCEDO1)
DCL VAR(&QDATALEN) TYPE(*DEC)  LEN(5 0)
DCL VAR(&QDATA)    TYPE(*CHAR) LEN(5)
DCL VAR(&WAIT)     TYPE(*DEC)  LEN(5 0) VALUE(-1)
DCL VAR(&USER)     TYPE(*CHAR) LEN(10)
RTVJOBA USER(&USER)
DOWHILE (1=1)
    CALL QRCVDTAQ (&QNAME &QLIB &QDATALEN &QDATA &WAIT)
    IF (&QDATA = 'END') (DO)
       SNDMSG     MSG('Program RCVDTAQC ended. END flag received.') +
                    TOUSR(&USER)
        RETURN
    ENDDO
    SNDUSRMSG  MSG('Order number' *BCAT &QDATA *BCAT 'has been printed.') +
                 MSGTYPE(*INFO) TOUSR(&USER)
ENDDO
ENDPGM 
				
			

Explanation:

Line 1: Program starts

Line 2: Name of the data queue. In this case ANTDTAQ.

Line 3: Library of the data queue. In this case ANTDTAQLIB.

Lines 4: Length of the data received from the data queue. It is an output parameter.

Line 5: Variable to hold the data to received from the data queue.

Line 6: Variable to specify the time that the API will be waiting for a data to arrive. The time is in seconds and if you put a negative number the API will be waiting indefinitely.

Line 7: Variable to hold the user that runs the program that will be used to send the messages.

Line 8: Command to retrieve Job attributes, in this case the user that runs the program.

Line 9: Infinite loop.

Line 10: The API will wait for a data to arrive or if any data is in the data queue it will extract it and store it in &DATA. &DATALEN will store the length of the data read.

Line 11 – 15: If &QATA is equal to END, the end flag, the program will send a message indicating that is ended and then it will end.

Line 16: If &QDATA contains an order number, it will send a message indicating that the order has been printed (normally, this is where the call to the RPG program that prints the order would be coded).

Line 18: Infinite loop ends.

Line 19: Program ends.

Testing the application

It’s time to test the application. First, I will run SNDDTAQC, enter three order numbers, and then exit the program with F3, which means the end flag will not be sent.

Next, I will run RCVDTAQC in batch mode. The three order numbers will be processed from the data queue, and the program will remain active in batch since the end flag has not been received.

Finally, I will run SNDDTAQC again, this time sending two additional order numbers. However, I will exit with F6, which triggers the sending of the end flag. As a result, RCVDTAQC will process the new order numbers and then terminate once the end flag is detected.

So I run CALL SNDDATQC and I get a screen to enter the order numbers. I will enter numbers 11111, 22222 and 33333. Every time I enter an order number I get a confirmation message in the screen. I end the program with F3 so no confirmation flag is sent.

Now I’m going to submit to batch the program RCVDTAQC.

At this stage, three order numbers are present in the data queue. When the program is executed, it will process these entries and issue a separate message for each order to the user executing the program.

Running DSPMSG command you can view those messages.

Program RCVDTAQ is still running in batch because the end flag has not been sent yet.

The final step in testing the application is to send two additional order numbers and then end the program with F6, which sends the end flag.

As a result, as shown in the image, new messages appear in the message queue displaying the additional order numbers, and the receipt of the end flag indicates that program RCVDTAQC has terminated.

I hope you found this post useful. Stay tuned — part two, covering the use of Data Queues with ILE RPG, will be published shortly.

CPTServ
Privacy Overview

This website uses cookies so that we can provide you with the best user experience possible. Cookie information is stored in your browser and performs functions such as recognising you when you return to our website and helping our team to understand which sections of the website you find most interesting and useful.