· Jun 6, 2016

Is there a way to reassign $ZPARENT JOBbed process variable when parent process terminates?


I have a WebSocket application which spawns new process using JOB command.

Sometimes WebSocket connection can be terminated, and in the meantime I need to hold spawned process alive until it can be associated with the new WebSocket connection. (Do not suggest serializing process state here instead please)

Technically, in Caché WebSocket connection is represented by the class, which executes in its own process. This process is terminated when the connection is lost. In this case the JOBbed process does not terminates (thanks Edward), but it rely on $ZPARENT variable.

Is it possible to hold JOBbed process alive for a while? If yes, how to change $zparent variable of the spawned process when the new "parent" process will be ready?

Thank you.

Discussion (11)0
Log in or sign up to continue
Jobbed process runs independently of parent process.
Killing a  parent does not kill its children.

Oops. Thank you, it does not kill children process really.

In my application two processes already use interprocess communication. Child process rely on $ZPARENT variable. Is it possible to change it? Or the only way is to use custom variable to hold the parent's process ID?

Yes.  Use resources instead. Read the docs. $ZPARENT value is also a "resource" that's getting created with the process, so children processes can communicate events to a parent process easily. As processes you want to pass messages between are not parent and child,  you need to create and use explicitly named resources.

Thanks, Dmitry, this is very close to what can be true. But to use this I need to interrupt WaitMsg method and check if the global exists each... Second? The one idea I come up with is to set timeout for that: set st = $system.Event.WaitMsg(, 1) if $LG(st,1)=0 {/*check if the process is gone and wait again*/} else {/*handle message*/} but is this the best way to do it? Are there any sort of registering trigger or system "interrupt" for this?

but WaitMsg it is on parent's side, my control code ususaly like like this

    set resName="someresource"
    job ..someJob(jobsData,resName)
    set child=$zchild
    for {
        set $lb(sc,data)=$system.Event.WaitMsg(resName, 1)
        if sc<=0 {
        // do some staff with incomming data

But if you want to interrupt your child process, of course will be possible only from such process, if your process have some loops you may just check if parent still exists, if not, just stop working.

If you want to wait for either a signal or for termination of a process, you can use a lock:

  1. Process A takes out an exclusive lock.
  2. Process B attempts to lock the same name.
  3. Process A either releases its lock or terminates.
  4. Process B will then get its lock.

You may need an extra synchronization step between steps 1 and 2 to ensure that A gets the lock before B does.

In steps 2 and 4, multiples processes can wait for a shared lock on the same name, and they will all be triggered at the same time.