|
|
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
|