Something like this:
from java.lang import Thread
from java.util.concurrent import ConcurrentHashMap
g = system.util.persistent("long-lived-thread")
# The .setdefault method will not replace an existing key, and
# is thread-safe (concurrent).
chm = g.setdefault('chm', ConcurrentHashMap())
tagpath = '[default]path/to/boolean/tag'
# Rely on closures/globals to make above available in the thread
def liveLongAndProsper():
me = Thread.currentThread()
# A ConcurrentHashMap's .put() method has the handy behavior of
# atomically replacing and **returning** the previous value for
# the given key.
priorThread = chm.put('running', me)
# If something was already running, interrupt it and join it.
if priorThread:
priorThread.interrupt()
priorThread.join()
# Not quite an infinite loop
while not Thread.interrupted():
v = system.tag.read(tagpath).value
system.tag.writeSynchronous(tagpath, not v)
# Sleep is only appropriate in a dedicated thread like this one
Thread.sleep(5000)
system.util.invokeAsynchronous(liveLongAndProsper)
So this turns on when anything references its script module. And lives “forever”, or a successor kills it. You can turn it off with this:
priorThread = someScriptModule.chm.get('running')
if priorThread:
priorThread.interrupt()
It won’t start on an inactive gateway, but won’t die. You’ll want the loop to check the gateway redundancy status if that’s important.