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
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()
class PyonThread(object): """ Thread-like base class for doing work in the container, based on gevent's greenlets. """ 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 def _pid(self): """ And internal, non global thread identifier. """ return id(self.proc) def _spawn(self): """ Spawn a gevent greenlet using defined target method and args. """ gl = spawn(self.target, *self.spawn_args, **self.spawn_kwargs) gl.link( lambda _: self.ev_exit.set()) # Set exit event when we terminate gl._glname = "ION Thread %s" % str(self.target) return gl def _join(self, timeout=None): return self.proc.join(timeout) def _stop(self): return self.proc.kill() def _running(self): return self.proc.started def _notify_stop(self): pass @property def pid(self): """ Return the internal process ID for the spawned thread. If not spawned yet, return 0. """ if self.proc is None: return 0 return self._pid() @property def running(self): """ Is the thread actually running? """ return bool(self.proc and self._running()) def start(self): self.proc = self._spawn() self.proc._glname = "" return self def notify_stop(self): """ Get ready, you're about to get shutdown. """ self._notify_stop() def stop(self): if self.running: self._stop() if self.supervisor is not None: self.supervisor.child_stopped(self) return self def join(self, timeout=None): if self.proc is not None and self.running: self._join(timeout) self.stop() return self def get(self): """ Returns the value (or raises the exception) of the wrapped thread. If not running yet, returns None. """ if self.proc is not None: return self.proc.get() return None def get_ready_event(self): """ By default, it is always ready. Override this in your specific process. """ ev = Event() ev.set() return ev
class PyonThread(object): """ @brief Threadlike base class for doing work in the container. Wraps gevent's greenlet class. """ 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() def _pid(self): return id(self.proc) def _spawn(self): # Gevent spawn gl = spawn(self.target, *self.spawn_args, **self.spawn_kwargs) gl.link(lambda _: self.ev_exit.set()) gl._glname = "ION Thread %s" % str(self.target) return gl def _join(self, timeout=None): return self.proc.join(timeout) def _stop(self): return self.proc.kill() def _running(self): return self.proc.started def _notify_stop(self): pass @property def pid(self): """ Return the process ID for the spawned thread. If not spawned yet, return 0. """ if self.proc is None: return 0 return self._pid() @property def running(self): """ Is the thread actually running? """ return bool(self.proc and self._running()) def start(self): self.proc = self._spawn() self.proc._glname = "Container process supervisor" return self def notify_stop(self): """ Get ready, you're about to get shutdown. """ self._notify_stop() def stop(self): if self.running: self._stop() if self.supervisor is not None: self.supervisor.child_stopped(self) return self def join(self, timeout=None): if self.proc is not None and self.running: self._join(timeout) self.stop() return self def get(self): """ Returns the value (or raises the exception) of the wrapped thread. If not running yet, returns None. """ if self.proc is not None: return self.proc.get() return None def get_ready_event(self): """ By default, it is always ready. Override this in your specific process. """ ev = Event() ev.set() return ev