tnt400.com - AS/400 Tips And Techniques

Sponsored by news400.com

This page is a discussion on the mentioned topic.
Most of the answers are in their original posted form, including any technical/spelling/grammatical errors.
No guarantees are expressed or implied. :-)
Comments, corrections, concerns about this tip?

Got another AS/400 question? Ask it here


What's New?
See what's new at Tips-N-Tech.

AS/400 Tips-N-Tech
AS/400 tips, techniques, and FAQ. Updated frequently.
CODEPage/400
All the code samples you can eat! RPG, CL, DDS, etc. etc.
AS/400 FAQs
The official news400.com FAQs.






All AS/400 Tip Categories / AS/400 Programming / What are data queues and how to use


Question:

Can anyone that actually know, explain to me what are data queues, what the benefit of using them are, and how to use them. An IBM book number would greatly be appreciated?

I am considering using them in a system we are writing at work to get our AS400 to dial out on an asynchronous line to Transunion for credit checks. This program will be accessed by a number of Service Reps. and I am hoping that a Data Queue Guru will shed some light on the in's and out's.


Answer(s):



Data Queues are a cross between data areas, and message queues. They are a method for asynchronous communication between programs. A typical use for a data queue is to have a job sitting in a batch subsystem waiting for a data queue entry to be created, and multiple programs dropping entries into the data queue. The ERP system my company uses has a single process to print invoices which is triggered by entries from multiple order entry staff to the data queue.

It sounds like your application fits the bill for using data queues. There are API programs to read and write to data queues, and they are quite straight-forward to use. If memory serves, they are QSNDDTAQ and QRCVDTAQ, and they are well documented in the book, although I don't know the number. If you like I can send you examples.

Benefits:
- performance can be dramatically improved over individual submits if the job is complex
- record locking conflicts are eliminated if only one job is updating.
- they can facilitate clean modular design


Drawbacks
- they are hard to document well - the next programmer will have to think to figure them out
- they can't really be audited, backed up, or for that matter conveniently examined.
- the contents are almost invisible, although smart programmers have written program to read the queue, print the entry, and re-write it.
- Once the entry is read it is gone; if the program halts the entry is lost. This can be gotten around with an audit file; write a record when the entry is written, nad have the receiver program update a status field when done.

Also, data queues don't support data definition, so you do need to use data structures if you intend to pass more than a single data element. In the example above, the data queue holds the order to be invoiced as well as the output queue to place the spooled file and the user to notify when it is printed.

Hope this helps!




Explaining them to a 'data queue beginner' is maybe easiest by comparing them to other objects to see similarities and differences. Then you can get into purpose and useability.

A data queue is similar to a database file that has records written to it. One program (or many programs) can send entries to the queue. Each entry is similar to a record. Another program (or many programs) can read entries back from the queue, similar to reading records.

Differences to begin with are in formats (record descriptions), reading the same entries more than once and speed.

An entry on a data queue has no external description; it's just a string of bytes. If you want something like "fields", you'll have to do all the concatenating and substringing yourself.

Normally, an entry is read only once. When the entry is read off the queue, it is gone. The first program to read the entry gets it and then it's gone. (It's possible to get around this, but there's seldom a reason to.)

Data queues are designed to provide fast communication between programs. You might have a dozen programs feeding entries onto a queue and a single program receiving those entries. The entries might represent transactions that you want performed against your database and you don't want those dozen programs all doing it individually. You centralize the process in the receiver program. The time it takes for an entry to be sent from one program and be received by another is minimal, less than if you used a file to hold records.

Alternatively, you might have one program feeding entries as fast as it can onto a queue and have a dozen programs receiving entries. By having the transactions processed by a dozen programs, you can multiply the work being done. And since each entry is removed from the queue when it's received, you don't have to worry about another program getting the same entry.

The speed is partially achieved by eliminating any overhead done by the system. An example is the way the system handles the space used by a data queue as entries are added and removed. If you start a program up to add entries to the queue but there's no program started to receive the entries, the allocated space gets bigger. When the entries are later received and removed from the queue, the space allocated does _not_ get smaller. You must delete and recreate the data queue to recover excess space if want it back. This means you must know the original parameters used to create the *DTAQ object so you can recreate one to match. (There's an API to get this info that you can get into later.)

If you prefer, you can think of a *dtaq as being similar to a message queue. You can send messages from one program and another can receive them from the *msgq. If you do a RCVMSG RMV(*YES), the message is gone from the *msgq, similar to how an entry is removed from a *dtaq. And a *dtaq entry has a format similar to a message; i.e., there's no format except what you create yourself. (Note that MSGDTA() can be used to provide some general formatting with a message.)

Entries are generally sent by calling the QSNDDTAQ API and received by calling the QRCVDTAQ API. One handy use for me is in CL programs where you're limited to a single file declaration. If you use these APIs, you can use any number of *dtaqs to simulate physical files, either for passing info from one part of a program to another or for passing to a different program(s).

Perhaps start by creating a *dtaq with CRTDTAQ and writing a program to send some entries to it. Then do a DMPOBJ and examine the output. Then write a second program to receive the entries and do a second DMPOBJ. Testing it out can be done with some pretty small CLPs.

Data queue APIs are technically described for Version 4 in the OS/400 Object APIs manual on the Systems Programming Support Bookshelf.

Good luck.




Here are some parts from the IBM OS/400 manuals.

http://publib.boulder.ibm.com/cgi-bin/bookmgr/BOOKS/QB3AMQ02/1.0
http://publib.boulder.ibm.com/cgi-bin/bookmgr/BOOKS/QB3AVC00/B.8
http://publib.boulder.ibm.com/cgi-bin/bookmgr/BOOKS/QB3AUO01/3.5.7
http://publib.boulder.ibm.com/cgi-bin/bookmgr/BOOKS/QB3ALE01/2.3.3.2
http://publib.boulder.ibm.com/cgi-bin/bookmgr/BOOKS/QB3ALC01/D.28
http://publib.boulder.ibm.com/cgi-bin/bookmgr/BOOKS/QB3AUP01/3.1.438
http://publib.boulder.ibm.com/cgi-bin/bookmgr/BOOKS/QB3AUP01/3.1.1337
http://publib.boulder.ibm.com/cgi-bin/bookmgr/BOOKS/QB3AUP01/3.1.558

Shameless plug :-) I located those books with my Find/400 page
http://www.xs4all.nl/~hgj/find400.html




They work quite easily: One program stores information in then :

       CALL 'QSNDDTAQ'             90
       PARM 'DTQ_PMC' P1DTAQ 10            (name of the dataqueue)
       PARM '*LIBL'   P1DLIB 10                     ( libl of the dataqueue)
       PARM 8         P1LEN   50                 (length of answer)
       PARM           P1RC                           ( answer)
-

The background job reads the information

                 CALL 'QRCVDTAQ'             9192
                 PARM 'DTQ_PMC' P1DTAQ 10
                 PARM '*LIBL'   P1DLIB 10
                 PARM           P1LEN   50
                 PARM           P1RC
                 PARM -1        P1WAIT  50   (wait till somebody puts
something in it)

If the background job receives a 9 the program stops receiving. Quit simple, but effective.




Others described how data queues enable asynchronous communications between multiple jobs running on AS/400. Another aspect is the ability to communicate between PC programs and AS/400 jobs via Client Access APIs. For info on this go to the Info Center:

http://publib.boulder.ibm.com/html/as400/infocenter.htm

Select Information Center, then
Client Access Express, then
Programming, then
Express C/C++ APIs




The data queue is a very simple concept. In your application you would have a single job that handles credit checks. When a credit check is needed, the program talking to the service rep sends a message to the data queue for the credit check job. This "wakes up" the waiting credit check job and it proceeds to dial and do the credit check. When it's done it sends a message back to a data queue for the requesting job, waking that job back up and giving it the results of the check.

You can do various things, like have the credit check job check the incoming data queue for new messages needing processing before hanging up the line after completing a credit check. Just use a "dequeue but don't wait" operation in this case, vs the usual "dequeue with wait" operation.

For some reason queues are rarely used (or provided as primitives) in computer systems, even though they are one of the most efficient and easiest to manage mechanisms for synchronizing multi-threaded applications.





Other tips in this category:

Click here to see all categories.

Socket Programming And Timeout Issues
Deleting Duplicate Records From A Table
What are data queues and how to use
Retrieving SMTP Name
RPGLE example for Dynamic Screen Manager API
Calling APIs from CL - with examples!
Compare two strings in RPG character by character
How to search all pgms in QCLSRC for a keyword
Retrieve Database File Description (QDBRTVFD) API
How to redirect the output to STDERR from RPG-IV
Using Multiformat Logical To Join 2 Identical File
D-Spec *LIKE DEFN
RPG: Converting Character to Decimal
Example of ILE RPG CGI Program
Handling ILE RPG Numeric Overflow
Help with Subfile Programming in RPG III
Zoned parameter in ILE RPG
What's the best way to do modulus in CL?
RPG Nesting Source Print Utility
More on changing the SIGNON screen
A silly ILE RPG question
Calling Validation List API From ILE RPG
Soft Coding Module Names
RPG Multidimensional Arrays in Action
Build a Page-Equals-Size Lookup Window
Procedures within an ILE RPG program
Break msg from RPG
Source Debugger for batch jobs
RPGLE debugging
Timing out display sessions in DDS
Building Dynamic Stored Procedures
Put Message in System Log
Dynamic RPGSQL
Randomize function for the AS/400
What's the fastest way to do a simple RPG lookup?
First time Data queue application in RPG
Print file overflow in ILE RPG
Mapping Fields To Arrays in ILE RPG
Named inidicators
STRQMQRY: comparision operator '=' isn't correct?!
DSPDTAARA to an outfile - possible?
PCL ESC codes in RPG
Sharing DB files between two AS/400s
Help: AS/400 subfiles
How do you change the signon screen?
Determining Even/Odd Values in queries
Get day of the week in RPG
Convert UPPERCASE to lowercase
RPG IV help using APIs
Help with data area API
Detecing IFS Files from RPG
SQL in a CL program
Calling AS/400 APIs from ILE RPG
CVTDAT command to convert an *MDY to a *LONGJUL
CPYSPLF Automation
Subfile Window background problem
Using IFS APIs w/ ILE RPG
Packed or unpacked fields?
QRYDFN to source and back
What does the "optimize" parm do?
Determining the calling program
Sockets in RPG?
Sorting a user space
OVRDBF and SECURE() keyword in an ILE environment
RPG record locking
RPG Differences: V2R3 to V3R2 upgrade
Getting the relative record number (RRN)
What is the longest parameter usable in RPG?
A C function that returns a string to an RPG pgm
Problems with ZADD *ZEROS
Can you highlight code in SEU?
Reusing deleted records - OK?
Is there an easy way to change edit codes?
Help - Windowed Subfiles
Logical Files and DDS
AS/400 'machine language' - MI Programming
Library lists and performance
How to use ERRSFL
Updating in CL
Record lock wait time
Message subfile problem
Physical File Joins
CL: Copying User Profiles
Commands and PARM
ILE RPG, RPG IV, vs. RPG/400
RPG and subfiles
Multiple subfiles
Field masking for passwords
SFLMODE keyword in an ILE program
Subfile size
Color coding records in a subfile
MSGLINE in windows
Controlling cursor movement on a display file
API returns error! Why?
Put an RPG Program on the Web
Variable length records in RPG
Differences Between RPG400, RPG IV, and ILE RPG


You are at a news400.com site.
Contact Us | Report Bugs | Submit Comments/Suggestions | Read Site Use Agreement | Read Privacy Policy
Copyright © 2000 Duke Communications International.
This site is best viewed with the latest versions of Netscape or Internet Explorer, 800 x 600 resolution (or higher), and at least 256 colors.
Duke Communications   NEWS/400 | 29th Street Press | Business Finance | DominoPro | Selling AS/400 Solutions | SQL Server Magazine | Windows NT Magazine