Reference Type: Supported, Category: TaskMan, Integration Agreement: 10063
^%ZTLOAD is the main API used to create and schedule tasks (commonly
referred to as "queuing"). Queuing tells TaskMan to use a background
partition to DO a certain API at a certain time, with certain other
conditions established as described by the input variables.
This API, as used in code, behaves consistently so most queuers strongly resemble one another. The queuer can be written so that it is either interactive with the user or so that it is not interactive. The standard variations on this structure deserve attention.
Make sure to perform the following steps before calling this API:
(required) The API TaskMan will DO to start the task. You can specify it as "LABEL^ROUTINE" or "^ROUTINE" or "ROUTINE".
(required) Task description, up to two hundred characters describing the task, with the software application name at the front. While not required, use of this variable is recommended.
(optional) Start Time when TaskMan should start the task. It must be a date and time in VA FileMan or $HOROLOG format. Setting it to "@" will cause the task to be created but not scheduled. If ZTDTH is not set, ^%ZTLOAD asks the user for the start time.
(optional) The I/O device the task should use. If ZTIO is NULL, no
device is used. If undefined, the current I/O variables will be used to select
a device. ZTIO should only be used when the current I/O variables do not
describe the needed device. If you do not need a device for a job, set ZTIO="".
ZTIO accepts the same I/O formatting string as IOP.
(optional) UCI the task should use. The current UCI is used if ZTUCI is undefined.
(optional) Volume Set:CPU. Specifies the name of the volume set
and CPU on which the task should run. The volume set can be passed
in the first :-piece, and the CPU in the second. Neither piece of
information is required; either can be passed without the other. If the CPU alone is passed, it must
still be preceded by a ":" (e.g., :ISC6A1). If the volume set is not
passed, TaskMan will run the task on the volume set it came from or on a print
server. If the CPU is not passed, TaskMan will run the task on the CPU where
TaskMan resides. Any volume set and/or CPU specified by the task's I/O device
takes precedence over the same information passed here.
(optional) The CPU priority the task should receive. It should be an integer between 1 (low) and 10 (high). The site's default for tasks is used if this is undefined.
(optional) Input variable array. An array whose nodes specify
input variables to the task beyond the usual set all tasks receive. There are
four kinds of nodes this array can have:
(optional) KEEP UNTIL. Set this to the first day the Task File Cleanup can delete this task. It should be a date and time in FileMan or $HOROLOG format. Use of this variable is recommended when ZTDTH equals "@".
(optional) Name of a SYNC FLAG. Using SYNC FLAGS allows TaskMan to
run the next task in a series of tasks only if the preceding task in the series
(Usually returned) The task number assigned to a task, returned
whenever a task is successfully created. It can be used as an input variable
to the other TaskMan application mode APIs.
START TIME (usually returned) contains the task's requested start time in $HOROLOG format. It is returned whenever ZTSK is returned, and gives you a way to know the start time a user requests.
The VistA Standards and Conventions require that anywhere you let a user
pick the output device you also let the user choose to queue the
Often one part of the queuer is a call to ^%ZIS (the Device Handler). When you set up the variables for your call, include a "Q" in the variable ^%ZIS so the Device Handler will let the user pick queuing. After the Device Handler call (and after you check POP to ensure that a valid device was selected), you can check $DATA(IO("Q")) to see whether the user chose to queue to that device. If so, then you must queue the printout you were about to do directly, and your software should branch to the code to set up the task. A sample of the code for this kind of print queuer looks something like this:
SELECT ;select IO device for report S %ZIS="Q" D ^%ZIS I POP D CANCEL Q I $D(IO("Q")) D QUEUE Q D PRINT,^%ZISC Q ; QUEUE ;queue the report S ZTRTN="PRINT^ZZREPORT" S ZTDESC="ZZ Application Daily Report 1" S ZTSAVE("ZZRANGE")="" D ^%ZTLOAD I $D(ZTSK)[0 W !!?5,"Report canceled!" E W !!?5,"Report queued!" D HOME^%ZIS Q
The code to set up the task after the call to ^%ZIS has four steps.
First, it sets the ^%ZTLOAD input variables to define the task. Second, it
calls ^%ZTLOAD to queue the task. Third, it checks $DATA(ZTSK)#2 to find out
whether a task was really queued and provides appropriate feedback. Fourth, it
calls HOME^%ZIS to reset its IO variables.
NOTE: This queuer did not define ZTIO. Print queuers can take advantage of the fact that they directly follow a ^%ZIS call that sets up all the IO variables they need. Under these conditions, the queuer code can rely on ^%ZTLOAD to identify the task's IO device from the IO variables, thus, saving the programmer the work of building the correct ZTIO string.
Notice also that when queuing output, we need not call ^%ZISC to close the IO device because when the user chooses to queue output the Device Handler does not open the device. Thus, all we need to do here is reset our IO variables with a HOME^%ZIS call.
As usual in these kinds of queuers, we did not define ZTDTH, but instead let ^%ZTLOAD ask the user when the report should run.
Finally, notice that we tell the task to begin at PRINT, the same tag used by the trigger code to start the foreground print when the user chooses not to queue. Under most circumstances, print queuers can use most of the same code for their tasks that the foreground print uses.
Under certain conditions, queuers must create and schedule their tasks with no interaction with the user. Examples include queuers operating out of tasks or queuers that need to run without the users' knowledge. Only two items must be changed from interactive queuers to make non-interactive queuers work:
After the call to ^%ZTLOAD, you may (or may not) want to issue feedback messages.
Certain tasks need no IO device. These include primarily tasks that rearrange large amounts of data but produce no report, such as filing and compiling tasks. Two different kinds of non-IO tasks exist:
Queuers for concurrent non-IO tasks need only set ZTIO to NULL, and
TaskMan will run the task, with no IO device.
For sequential non-IO tasks, queuers must set ZTIO to the name of a resource type device. TaskMan will then ensure that the tasks run single file, one after the other in order by requested start time. Applications that need sequential non-IO tasks should instruct system managers in the Package Installation Guide to create a resource device with the desired characteristics so that these queuers can safely queue their tasks to them. Such devices should be namespaced by the software application that uses them. SYNC FLAGs can also be used to allow the next task in a series to start only if the previous task in the series completed successfully.
NOTE: For more information on SYNC FLAGs, please refer to the "Using SYNC FLAGs to Control Sequences of Tasks" topic in the "TaskMan Programmer Tools" chapter in the Kernel Developer's Guide.
This example is a job that consists of gathering
information and then printing it. Assume that the gathering takes a few
hours. We do not want the device that the user selects to be tied up for
that time, so we divide the job into two tasks. The first task gathers the
information and the second task prints it. We use the
API to select the device, the ^%ZTLOAD API to queue the print task, and the
^%ZTLOAD API to schedule the gather task. We use the
API to schedule the print task when the gather task finishes.
NOTE: This process is made easier by using the $$QQ^XUTMDEVQ and $$REQQ^XUTMDEVQ APIs.
ARHBQQ ;SFVAMC/GB - Demo of 'gather' and 'print' in 2 tasks ;1/19/06 08:31 ;;1.1 ZTLOAD ; N ARH,ARHZTSK,X,ZTSAVE,%ZIS,ZTSK,ZTDTH,ZTRTN,ZTDESC,ZTIO,POP W !,"Queue the second task (the print task) first.",! ;Let's deal with the second task first. ;The user doesn't know it, but he's actually queuing the second task, ;the "print" portion of the job. The only question the user will be ;asked is to select the device. ; S %ZIS="QM" S IOP="Q" ;Force queuing. D ^%ZIS Q:POP ; Select Device W !,"Finished with %ZIS." ; S ZTDTH="@" ;Don't schedule the task to run, we'll do it later ;If we didn't need to set ZTDTH, we could use EN^XUTMDEVQ, but that ;API 'new's ZTDTH, so we can't set it. ; ;BTW, Did you know that there's a 5th parameter in EN^XUTMDEVQ? ;Usually, EN^XUTMDEVQ will 'new' ZTSK, so you can't get to it. ;If you put "1" as the 5th parameter, ZTSK will exist when EN returns. ;D EN^XUTMDEVQ("PRINT^ARHBQQ","ARHB Print",.ZTSAVE,.%ZIS,1) ; S ZTRTN="PRINT^ARHBQQ" S ZTDESC="ARHB Print" D ^%ZTLOAD D HOME^%ZIS W !,"ZTSK=",$G(ZTSK) Q:'$D(ZTSK) S ARHZTSK=ZTSK ; N ZTSAVE,%ZIS,ZTSK,ZTDTH,ZTRTN,ZTDESC,ZTIO,IOP W !,"Now queue the first task (the gather task).",! ;Now queue the first task, the "gather" portion of the job. ;Since we don't need a device, ;the user will only be asked when to start the task. ;(I wasn't able to get EN^XUTMDEVQ to work for me. I tried setting ;IOP="Q;" to let it know that it should be queued and it didn't need ;a device, but it did nothing, and returned a null ZTSK.) F I="ARHZTSK" S ZTSAVE(I)="" ; Save the ZTSK of the "print" task. S ZTIO="" ; We don't need a device. S IOP="Q" ; Force queuing. S ZTRTN="GATHER^ARHBQQ" S ZTDESC="ARHB Gather" D ^%ZTLOAD D HOME^%ZIS W !,"ZTSK=",$G(ZTSK) Q GATHER ; N ARHJ S ZTREQ="@" S ARHJ="ARHB-QQ"_"-"_$J_"-"_$H ; namespace + unique ID K ^XTMP(ARHJ) ; Use ^XTMP to pass a lot of data between tasks. S ^XTMP(ARHJ,0)=$$FMADD^XLFDT(DT,1)_U_DT ; Save-thru and create dates. S ^XTMP(ARHJ)="HI MOM!" ; Pretend this is a lot of data. D SPRINT Q SPRINT ; Now schedule the "print" task to run. N ZTSK,ZTDTH,I,ZTRTN,ZTDESC,ZTIO,ZTSAVE ; Very important to NEW the ; input variables to REQ^%ZTLOAD, otherwise they retain the values of ; the currently running task, and you could unintentionally change the ; "print" task to rerun the "gather" task. F I="ARHJ" S ZTSAVE(I)="" ; Let the "print" task know the "$J" value. S ZTSK=ARHZTSK S ZTDTH=$H D REQ^%ZTLOAD ;Instead of the above 8 lines we could have simply: ;S X=$$REQQ^XUTMDEVQ(ARHZTSK,$H,"ARHJ") Q PRINT ; S ZTREQ="@" U IO ; Don't need this if invoked using a ^XUTMDEVQ API. W !,"The secret message is: '",$G(^XTMP(ARHJ)),"'" K ^XTMP(ARHJ) Q
VAH>D ZTLOAD^ARHBQQ Queue the second task (the print task) first. QUEUE TO PRINT ON DEVICE: HOME// P-MESS 1 P-MESSAGE-ENGWO-HFS-VXD HFS FILE ==> MAILMESSAGE 2 P-MESSAGE-HFS-VXD HFS FILE ==> MAILMESSAGE Choose 1-2> 2 <Enter> P-MESSAGE-HFS-VXD HFS FILE ==> MAILMESSAGE Subject: MY PRINT Select one of the following: M Me P Postmaster From whom: Postmaster// <Enter> Send mail to: KRNUSER,ONE// <Enter> KRNUSER,ONE Select basket to send to: IN// <Enter> And Send to: <Enter> Finished with %ZIS. ZTSK=2921497 Now queue the first task (the gather task). Requested Start Time: NOW// <Enter> (JAN 25, 2005@11:30:35) ZTSK=2921499
Subj: MY PRINT [#28881111] 01/25/05@11:30 2 lines From: POSTMASTER (Sender: BEUSCHEL,GARY - COMPUTER SPECIALIST) In 'IN' basket. Page 1 *New* ------------------------------------------------------------------------------- The secret message is: 'HI MOM!' Enter message action (in IN basket): Ignore//
September 15, 2011