def get_ready_event(self): """ By default, it is always ready. Override this in your specific process. """ ev = Event() ev.set() return ev
def ensure_ready(self, proc, errmsg=None, timeout=20): """ Waits until either the thread dies or reports it is ready, whichever comes first. If the thread dies or times out while waiting for it to be ready, a ContainerError is raised. You must be sure the thread implements get_ready_event properly, otherwise this method returns immediately as the base class behavior simply passes. @param proc The thread to wait on. @param errmsg A custom error message to put in the ContainerError's message. May be blank. @param timeout Amount of time (in seconds) to wait for the ready, default 20 seconds. @throws ContainerError If the thread dies or if we get a timeout before the process signals ready. """ if not errmsg: errmsg = "ensure_ready failed" ev = Event() def cb(*args, **kwargs): ev.set() # link either a greenlet failure due to exception OR a success via ready event proc.proc.link_exception(cb) ready_evt = proc.get_ready_event() ready_evt.rawlink(cb) retval = ev.wait(timeout=timeout) # unlink the events: ready event is probably harmless but the exception one, we want to install our own later ready_evt.unlink(cb) # if the thread is stopped while we are waiting, proc.proc is set to None if proc.proc is not None: proc.proc.unlink(cb) # raise an exception if: # - we timed out # - we caught an exception if not retval: raise ContainerError("%s (timed out)" % errmsg) elif proc.proc is not None and proc.proc.dead and not proc.proc.successful( ): raise ContainerError("%s (failed): %s" % (errmsg, proc.proc.exception))
def __init__(self, target=None, *args, **kwargs): """ @param target The Callable to start as independent thread @param args Provided as spawn args to thread @param kwargs Provided as spawn kwargs to thread """ super(PyonThread, self).__init__() if target is not None or not hasattr( self, 'target'): # Allow setting target at class level self.target = target self.spawn_args = args self.spawn_kwargs = kwargs # The instance of Greenlet or subprocess or similar self.proc = None self.supervisor = None self.ev_exit = Event() # Event that is set when greenlet exits