1748109 Members
4691 Online
108758 Solutions
New Discussion

F$getqui

 
SOLVED
Go to solution
mrityunjoy
Advisor

F$getqui

 I need to add one check in my code which will check if the job which is submitted is in executing state or pending state .If it is in pending state then it will wait for the job to go for execution before going to next loop.

Mrityunjoy Kundu -AST (TCS)
8 REPLIES 8
Steven Schweda
Honored Contributor

Re: F$getqui

 
Hoff
Honored Contributor

Re: F$getqui

And for additional examples of DCL tools and lexical functions check the Freeware for tools and options.  

 

Google is your friend here, particularly given that there are thirty years of DCL examples and tools accumulated on the Freeware and "SIG tape" distributions.

 

Sites including www.decuslib.com and www.digiater.nl have archives - the HP archives are woefully incomplete, unfortunately.  

 

With Google, you can use the site: keyword to target your search for examples to particular servers, too.

Hein van den Heuvel
Honored Contributor
Solution

Re: F$getqui

Hmm, a bit of an odd requirement, but perhaps I am mis-interpreting.

F$GETQUI is powerful and thus potentially tricky.

With wildcarda and contexts it let's you do a lot as pointed out.

There are some simple sage cases, which might just apply here.

 

When a job is submitted, the DCL symbol $ENTRY is defined.

The symbol can be used to interrogate the entry status by status name, or by status numeric value.

 

$ write sys$output $entry, " ", f$getq("DISPLAY_ENTRY","JOB_PENDING  ",$entry)

and

$ write sys$output $entry, " status=", f$getq("DISPLAY_ENTRY","JOB_STATUS",$entry)

 

The DCL code below submits a (faked) job a few times, but not waits if a prior submit is pending, as i believe you wanted to know how to do.

To test it, define SYS$BATCH to a queue with job-limit of 1.

There are ample timing/race conditions in the script, which are mostly NOT handled


fwiw,
Hein

 

$ tmp := "wait_a_while.tmp"
$ times_to_submit = 3
$
$ if "".eqs.f$search(tmp)
$ then
$   open/write tmp 'tmp'
$   write tmp "$ wait 0:0:10"
$   close tmp
$ endif
$ submitx/noprin/noti/noke/nolo 'tmp'  ! Initial submit, set up $ENTRY
$
$main_loop:
$ times_to_submit = times_to_submit - 1
$ if times_to_submit .lt. 1 then goto done
$ ! see if we are ready to submit next... executing or done.
$wait_loop:
$ write sys$output $entry, " status=", -
     f$getq("DISPLAY_ENTRY","JOB_STATUS",$entry)
$ executing = f$getq("DISPLAY_ENTRY","JOB_EXECUTING",$entry)
$ pending = f$getq("DISPLAY_ENTRY","JOB_PENDING",$entry)
$ if executing .or. executing .eqs. ""
$ then
$   submitx/noprin/noti/noke/nolo 'tmp'  ! new submit, new $ENTRY
$ else
$    if pending
$    then
$         write sys$output "Prior job still pending. Waiting for ", $entry
$         wait 0:0:3
$         goto wait_loop
$    else
$         write sys$output "Unexpected condition. Toodles."
$         goto done
$    endif
$ endif
$ goto main_loop
$done:

 

 

 

 

 

John Gillings
Honored Contributor

Re: F$getqui

As Hein has suggested, make sure you save $ENTRY immediately after the SUBMIT. That way you can use DISPLAY_ENTRY later and know you're dealing with your specific job. Note that $ENTRY is a LOCAL symbol, so if your SUBMIT is in a procedure, you may need to copy it into a global symbol for future use.

 

If you don't have $ENTRY, and the job you're interested in belongs to you, you can skip most of the complexities of F$GETQUI inquiring about the job by name with DISPLAY_ENTRY - but realise there may be more than one. The attached procedure will check if there is a job with the specified name in the requested state (and optionally on a specified queue). Note that there are several compound state masks, and it's easy to define your own. For example, state SHEDULED includes jobs in PENDING, HOLDING or TIMED_RELEASE states.

 

Return values are

TRUE - a job exists in the requested state

FALSE - job(s) exist but none are in the requested state (STS$M_INHIB_MSG is set to supress output messages) JBC$_NOSUCHENT - no matching job exists.

Global symbols returned 

FOUND_ENTRY  - the entry number of the matching job.

ENTRY_STATUS - the job status.

 

Example use

 

$ @JOB_STATE MYJOB RUNNING
$ IF $STATUS THEN WRITE SYS$OUTPUT "Job is in a running state"
$
$ @JOB_STATE ANOTHER_JOB SCHEDULED SYS$BATCH
$ IF $STATUS THEN WRITE SYS$OUTPUT "Job is scheduled on SYS$BATCH"
$

 

Waiting for a job to complete is easy, use SYNCHRONIZE, but waiting for it to go into a specific state will require polling. Consider that there are conditions where a job may not ever reach execution state - for an example, runaway or deadlocked job(s) which fill all execution slots in a queue. If that's the case your job will remain in PENDING state until a slot becomes available. You may want to have some kind of sanity timeout (or, if privileged, consider incrementing the queue JOB_LIMIT?)

 

(oh, and I just realised, I've included PENDING state in the RUNNING mask, you may wish to remove it - my logic was that PENDING means the job controller has released the job for execution).

A crucible of informative mistakes
John Gillings
Honored Contributor

Re: F$getqui

re: Steven, BATCH_CHECK.COM

 

Now I know you're going to tell me "It's been working for years", but beware, "status .eq. 256" is not necessarily going to work. Status is a mask, and there are (admittedly extremely rare) cases where multiple bits may be set, thus an equality test might not do what you expect. A safer test is "(status .AND. 256).NE.0". It's highly likely that you've never noticed a failure, but if it ever happens, chances are it will be at the worst possible time!

A crucible of informative mistakes
mrityunjoy
Advisor

Re: F$getqui

Thanks for all your kind response. I am a learner of scripting so want to be more specific. The existing script is as below:

 

$BACKUP_LOOP:
$ if f$type(files_'n') .nes. ""
$ then
$    open/write temp_file nbu$temp:image_temp.com;
$    files = files_'n'
$    write temp_file "$ SET VERIFY"
$    write temp_file "$ nbucmd :== $nbu$bpcd"
$    write temp_file "$ nbucmd SHOW CLIENT"
$    write temp_file "$ nbucmd BACKUP/DEBUG ''QUALIFIERS' ''FILES' "
$    write temp_file "$ EXIT"
$    close temp_file
$    submit/log=back$log/noprint/queue='backup_q'/user='backup_user' -
 /noke/notify /name=SYSBAK_BACK_IMAGE_'n nbu$temp:image_temp.com

 

This job is submitted on back$prd_batch which is a generic queue and then it goes to either of back$prd1_batch or back$prd2$batch execution queues depends upon the availabity.

 

I want to check while submitting the job if it's state is executing or pending. If it is in pending state then it will wait still the state goes to executiing state.

 

So I have added the below section:

$BACKUP_LOOP:
$ if f$type(files_'n') .nes. ""
$ then
$    open/write temp_file nbu$temp:image_temp.com;
$    files = files_'n'
$    write temp_file "$ SET VERIFY"
$    write temp_file "$ nbucmd :== $nbu$bpcd"
$    write temp_file "$ nbucmd SHOW CLIENT"
$    write temp_file "$ nbucmd BACKUP/DEBUG ''QUALIFIERS' ''FILES' "
$    write temp_file "$ EXIT"
$    close temp_file
$    submit/log=back$log/noprint/queue='backup_q'/user='backup_user' -
 /noke/notify /name=SYSBAK_BACK_IMAGE_'n nbu$temp:image_temp.com

$wait_loop:
$ write sys$output $entry, " status=", -
     f$getq("DISPLAY_ENTRY","JOB_STATUS",$entry)
$ executing = f$getq("DISPLAY_ENTRY","JOB_EXECUTING",$entry)
$ pending = f$getq("DISPLAY_ENTRY","JOB_PENDING",$entry)
$ if executing .or. executing .eqs. ""
$ then
$   submitx/noprin/noti/noke/nolo 'temp_file'  ! new submit, new $ENTRY
$ else
$    if pending
$    then
$         write sys$output "Prior job still pending. Waiting for ", $entry
$         wait 0:0:3
$         goto wait_loop
$    endif
$ endif
$ goto done
$done:

 

However the script is not going to wait_loop.

Help!!

Mrityunjoy Kundu -AST (TCS)
John Gillings
Honored Contributor

Re: F$getqui

>However the script is not going to wait_loop.

 

I don't understand this. Do you mean you're not reaching the label, or the GOTO back to the label isn't working? The exact output, including complete error messages might help.

 

Guessing... Your IF-THEN-ELSE-ENDIF blocks aren't complete - I can't see the ENDIF for the statement IF F$TYPE(files_'n') .nes. "" which means the label is inside an IF-THEN-ELSE block, which is not a good idea.

 

To put a loop inside an IF-THEN-ELSE, I usually code it as a GOSUB. 

 

I don't understand why you have a second SUBMIT command, when the job may be executing. What is 'temp_file'? (it was a logical name, until you closed it, but the second reference is to a symbol)

 

That said, think about what you're trying to achieve here. You're generating a temporary procedure then executing it as a batch job, and waiting around for it to do something. Why not replace all that complexity and just execute the commands directly? That way you know exactly what's happening, and you don't need to concern yourself with the state of the queues.

 

If you must use a batch job, you should close the potential timing windows by using SUBMIT/RETAIN=ALWAYS. That will ensure the job will remain on the queue after it executes, so you won't have the issue of the job completing and vanishing between the SUBMIT and the F$GETQUI. You'll then have to remember to DELETE/ENTRY='$ENTRY' once you're happy it's completed.

A crucible of informative mistakes
mrityunjoy
Advisor

Re: F$getqui

Now it is fixed. Thanks for all your help.

Mrityunjoy Kundu -AST (TCS)