Michael Davidovich · Feb 4, 2020

Check if $JOB is running?


For many routines we write, we utilize a global we name ^HITLIST($JOB,"routineName") as temporary storage as needed.  For various reasons this gets junked up and we are at a point where we need to do some routine garbage collection.

The idea is to write a utility that looks at all the ^HITLIST($JOB) nodes, check if the job is currently running and if it isn't then we can issues the KILL command on ^HITLIST($JOB).

We looked at the methods in %SYSTEM.Process and couldn't find a method that clear told us that a job was running or not.  The most promising seemed to be %SYSTEM.Process.State($J) but we tried both $J and the string "TEST" and got the result "RUN", so I'm not sure we understand its use.

There's documentation for %SYS.ProcessQuery which has an example where we capture a result set using the query %SYS.ProcessQuery:ListPids.  It seems to guarantee returning a result set of all processing running on the system.  We can run our ^HITLIST($JOB) node against this and manage appropriately.  This however is less real time than looking at the job number and calling a method to immediatily ask if it's running right now.

Does anyone have some other thoughts or reliable ways to check if a job is running?



1 588
Discussion (7)4
Log in or sign up to continue

I'd have to think a bit on what the "best" way to do this would be, but the following seems to work:


In my admittedly quick testing, it will return 0 for a process that doesn't exist.

The $job documentation put me on the path to look deeper into %SYS.ProcessQuery. The class documentation recommends using SQL to avoid the overhead of opening the object. It also recommends looking for a property that doesn't require sending a mailbox message to the process.


For example:

SELECT CommandsExecuted FROM %SYS.ProcessQuery where pid=5812

If the pid exists the query will return a row, otherwise it will return nothing. Hope that helps.

Thanks, @Vic_Sun.

I think %SYSTEM.Process.JobType() will be our best, simplest bet here.  It shouldn't be a ton of data to check that we can't brute force it.

Thanks said, I'm not familiar with using these class queries on a result set.  Can you point me to the starting documentation on that?



The easier the better:

 if $data(^$Job(PID)) // then the process with PID is running...

But each method mentioned above has a potential problem: if the process with PID had finished far ago, the O/S PID counter could run a full cycle, and another Caché (IRIS) process could start with the same PID. The full solution may worth a separate article, while the simple one is: just to collect garbage often enough. To my experience, once a day is usually quite enough even on high loaded systems.

Yes, it doesn't get easier than that!

Good point on the counter.

Thanks, Alexey!

Another suggestion.

You can define a %ZSTOP routine which would automatically clear ^HITLIST global on job end.

You can also use PPG which would be automatically deleted when job ends.

+1 for using PPG for this