1
import os
from kazoo.client import KazooClient
signal.signal(signal.SIGINT, signal_handler)

def signal_handler(signal,frame):
    print('\nYou pressed Ctrl+C!')
    print("Stopping...Process  "+process_id)
    print()
    children = zk.get_children("/assign2/root")
    l = [int(i[3:]) for i in children]
    l.remove(int(process_id))
    print("Min process id : ",min(l))
    zk.delete("/assign2/root/pid"+process_id, recursive=True)
    #To run a command on terminal --> os.system("python3 zook.py")
    if(int(process_id)==min(l)):
        print("Starting new process through :" , min(l))
        os.system("python3 zook.py")
    os.kill(int(process_id),0)
    zk.stop()
    sys.exit(0)

zk = KazooClient(hosts='127.0.0.1:2181')
zk.start()

zk.ensure_path("/assign2/root")
zk.create("/assign2/root/pid"+process_id, bytes(process_id, encoding='utf-8'),ephemeral=True)

On killing a process, I want to find the smallest of the remaining pids and start a process through the smallest pid.
I am using zookeeper to store pids as ephemeral znodes and upon terminating the python script in terminal, I'm trying to create another process.
I am able to create a process through the pid of the process I am terminating, but not from another pid of my choice.

Please let me know if there is a way to do this.

SherylHohman
  • 16,580
  • 17
  • 88
  • 94
  • When you say that you want to start a process "through" the smallest pid, what do you exactly mean ? – nsuneja Sep 02 '18 at 09:26
  • Assuming I run my python code zook.py , on three different terminals and if my process ids for the same are [1234,5678,4567] and the current process id is 5678. Now when I interrupt, I'll be killing the current process. But before I use os.kill() I want to run os.system("python3 zook.py") in the process 1234 and not in 5678 (which is happening now). So the process with the smallest pid of the remaining processes should run os.system("python3 zook.py") . – Prudhvi raj Sep 02 '18 at 18:16

1 Answers1

0

So, what you need here is monitoring all your different processes (each process monitoring all other), and wait for the failure of a process. In zookeeper world, this can be achieved via:

1) Zookeeper watches: Each zookeeper client (process) can set up a watch on the parent znode (In your case /assign2/root/) and watch for CHILD_DELETE events. You can have a look at the zookeeper documentation and the documentation of your specify library (kazoo) to see how you can do that. On setting up the watch, you can specify a callback which would be executed asynchronously, each time a znode under your parent znode disappears. This could happen because:

  • The child znode is ephemeral and the zk client which create that znode died.
  • The client explicitly deleted the child node. For example in your case you can delete the child node in the signal handler.

In this callback, each of the alive zookeeper clients/processes, will determine if its the lowest ranked process id (by fetching the list of all existing children under the parent znode), and if it is indeed the smallest pid, it will spawn the new process (python3 zook.py).

Note, that zookeeper watches are one-time fire concept. This means that after the watch has fired (i.e. the callback has executed), you would want to reset the watch at the very end of the callback execution, so that the next child delete event will also result in the callback firing.

2) The alternative approach is polling. In each of your process, you can have a dedicated thread which can periodically monitor the children of your parent znode, and each time a process detects that a node has disappeared, it can again determine if its the lowest alive pid and spawn a new process, if it indeed is.

Hope this helps. Let me know if you have any doubts. Would have liked to post the code you needed, but have to run for an errand.

nsuneja
  • 326
  • 1
  • 5