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

Hello!

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.

  • 0
  • 0
  • 169
  • 10
  • 1

Answers

Jobbed process runs independently of parent process.

Killing a  parent does not kill its children.

That said, you can use events for interprocess communication.

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.

Apparently I reached another question now. How to terminate child process if the parent process is gone? WaitMsg method in $system.Event class does not return when the parent process terminates.

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?

Wait interval can be very small so it's okay.

You could, I suppose, add some %ZSTOP code but that would be an overkill.

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 {
            quit:'$data(^$Job(child))
        }
        continue:data=""
        // 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.

Thank you, Jon, it's good to know all the ways how this can be implemented.