示例#1
0
    def get_ready_event(self):
        """
        By default, it is always ready.

        Override this in your specific process.
        """
        ev = Event()
        ev.set()
        return ev
示例#2
0
文件: thread.py 项目: mkl-/scioncc
    def get_ready_event(self):
        """
        By default, it is always ready.

        Override this in your specific process.
        """
        ev = Event()
        ev.set()
        return ev
示例#3
0
    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))
示例#4
0
    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
示例#5
0
文件: thread.py 项目: mkl-/scioncc
    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))
示例#6
0
文件: thread.py 项目: mkl-/scioncc
    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()
示例#7
0
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
示例#8
0
文件: thread.py 项目: mkl-/scioncc
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