Question
· Sep 11

Determine Job/Process State

Hi, I'm working on a large extraction from a database and need to parallelize the processes during the extraction.

Here's what happens:

  1. The user starts the extraction from.
  2. Several jobs are started using the Job <Method> instruction.

At the end, the user expects to find a document containing the results of all the extractions. What I'd like to do is start a new job that checks whether the previously started jobs have finished or are still working and consequently produce the document.

After starting each job, using $ZCHILD instruction I can get the ID of the last started job. I might create a list containing all these IDs, pass it to a method that checks if these jobs are still active and eventually produce the final result. The problem is that I can't figure out how to determine the status of a job given its Job ID.

I may use the retrieved ID to define a Job object using the command:

SET JobObj = ##class(%SYS.ProcessQuery).%OpenId($ZCHILD)

But after that, I can't figure out how to derive the job's status. There is a State property, but I can't understand which value indicates that the job has finished.

Thank you in advance if you can help me!

Discussion (8)4
Log in or sign up to continue

Hi Luis, thanks for responding me. 

However, I can't find the DEQ state in the documentation. 

Available states for the "State" property of the %SYS.ProcessQuery class are: 

LOCK - Executing a Lock command
OPEN - Opening a device
CLOS - Closing a device
USE - Using a device
READ - Read command
WRT - Write command
GET - Executing a $Get on a global
GSET - Setting a global
GKLL - Killing a global
GORD - $Order on a global
GQRY - $Query on a global
GDEF - $Data on a global
ZF - Executing a $ZF command
HANG - Executing a Hang command
JOB - Executing a Job command
EXAM - Executing a variable exam
BRD - Executing a broadcast
SUSP - Process is suspended
INCR - Executing a $Increment
BSET - Set $bitset
BGET - get $bitset
EVT - Waiting on event RUN - Process is running
 

If you want to wait for a group of child jobs to finish, you can do this with simple (incremental) locks:

Each child begins with:

    LOCK +^JOIN($JOB) SET ^JOIN($JOB)=$HOROLOG

and ends with:

    KILL ^JOIN($JOB) LOCK -^JOIN($JOB)

The parent can test that all the children have finished with:

    LOCK ^JOIN

    IF $DATA(^JOIN)=0 WRITE !,"One of the children died!"

There are lots of ways to expand on this. Add timeouts on the locks. Add a subscript before $JOB in whatever global you use to communicate the process join to have multiple simultaneous process joins. The parent can also look inside the ^JOIN global to diagnose which process died and possibly restart it.