Ejemplo n.º 1
0
 def test_event_clear(self):
     ev = Event()
     def waiter():
         self.assertTrue(ev.wait())
         ev.clear()
     evergreen.spawn(waiter)
     evergreen.spawn(ev.set)
     self.loop.run()
     self.assertFalse(ev.is_set())
Ejemplo n.º 2
0
 def test_event_kill_waiter(self):
     ev = Event()
     def waiter():
         ev.wait()
     t1 = evergreen.spawn(waiter)
     evergreen.spawn(t1.kill)
     evergreen.spawn(ev.set)
     self.loop.run()
     self.assertTrue(ev.is_set())
Ejemplo n.º 3
0
class Result(object):

    def __init__(self):
        self._event = Event()
        self._result = None
        self._exception = None
        self._used = False

    def is_set(self):
        return self._event.is_set()

    def set_result(self, value):
        if self.is_set():
            raise RuntimeError('already set')
        self._result = value
        self._event.set()

    def set_exception(self, exc):
        if self.is_set():
            raise RuntimeError('already set')
        self._exception = exc
        self._event.set()

    def wait(self, timeout=None):
        if self._used:
            raise RuntimeError('already used, clear it in order to use it again')
        self._event.wait(timeout)
        try:
            if self.is_set():
                return self._get_result()
            return None
        finally:
            self._result = self._exception = None

    def clear(self):
        self._event.clear()
        self._result = None
        self._exception = None
        self._used = False

    def _get_result(self):
        self._used = True
        if self._exception is not None:
            six.reraise(type(self._exception), self._exception)
        else:
            return self._result
Ejemplo n.º 4
0
class Result(object):
    def __init__(self):
        self._event = Event()
        self._result = None
        self._exception = None
        self._used = False

    def is_set(self):
        return self._event.is_set()

    def set_result(self, value):
        if self.is_set():
            raise RuntimeError('already set')
        self._result = value
        self._event.set()

    def set_exception(self, exc):
        if self.is_set():
            raise RuntimeError('already set')
        self._exception = exc
        self._event.set()

    def wait(self, timeout=None):
        if self._used:
            raise RuntimeError(
                'already used, clear it in order to use it again')
        self._event.wait(timeout)
        try:
            if self.is_set():
                return self._get_result()
            return None
        finally:
            self._result = self._exception = None

    def clear(self):
        self._event.clear()
        self._result = None
        self._exception = None
        self._used = False

    def _get_result(self):
        self._used = True
        if self._exception is not None:
            six.reraise(type(self._exception), self._exception)
        else:
            return self._result
Ejemplo n.º 5
0
class Task(tasklet):
    def __init__(self, target=None, name=None, args=(), kwargs={}):
        super(Task, self).__init__(parent=evergreen.current.loop.tasklet)
        self._name = str(name or _newname())
        self._target = target
        self._args = args
        self._kwargs = kwargs
        self._started = False
        self._exit_event = Event()

    def start(self):
        if self._started:
            raise RuntimeError('tasks can only be started once')
        self._started = True
        evergreen.current.loop.call_soon(self.switch)

    def run_(self):
        if self._target:
            self._target(*self._args, **self._kwargs)

    def join(self, timeout=None):
        """Wait for this Task to end. If a timeout is given, after the time expires the function
        will return anyway."""
        return self._exit_event.wait(timeout)

    def kill(self, *throw_args):
        """Terminates the current task by raising an exception into it.
        Whatever that task might be doing; be it waiting for I/O or another
        primitive, it sees an exception as soon as it yields control.

        By default, this exception is TaskExit, but a specific exception
        may be specified.  *throw_args* should be the same as the arguments to
        raise; either an exception instance or an exc_info tuple.

        """
        if self.dead:
            return
        if not self:
            # task hasn't started yet and therefore throw won't work
            def just_raise(*a, **kw):
                try:
                    if throw_args:
                        six.reraise(throw_args[0], throw_args[1],
                                    throw_args[2])
                    else:
                        raise TaskExit()
                finally:
                    self._exit_event.set()

            self.run_ = just_raise
            return
        evergreen.current.loop.call_soon(self.throw, *throw_args)

    def __repr__(self):
        status = "initial"
        if self._started:
            status = "started"
        if self.dead:
            status = "dead"
        if self._exit_event.is_set():
            status = "ended"
        return "<%s(%s, %s)>" % (self.__class__.__name__, self._name, status)

    @property
    def name(self):
        return self._name

    # internal

    def switch(self, *args, **kwargs):
        current = evergreen.current.task
        if current is not evergreen.current.loop.tasklet:
            raise RuntimeError('only the loop tasklet can switch to a Task')
        return super(Task, self).switch(*args, **kwargs)

    def throw(self, *args):
        current = evergreen.current.task
        if current is not evergreen.current.loop.tasklet:
            raise RuntimeError('only the loop tasklet can throw to a Task')
        return super(Task, self).throw(*args)

    def run(self):
        try:
            self.run_()
        finally:
            del self._target, self._args, self._kwargs
            self._exit_event.set()
Ejemplo n.º 6
0
class Task(Fiber):
    def __init__(self, target=None, name=None, args=(), kwargs={}):
        super(Task, self).__init__(target=self.__run,
                                   parent=evergreen.current.loop.task)
        self._name = str(name or _newname())
        self._target = target
        self._args = args
        self._kwargs = kwargs
        self._started = False
        self._running = False
        self._exit_event = Event()

    def start(self):
        if self._started:
            raise RuntimeError('tasks can only be started once')
        self._started = True
        evergreen.current.loop.call_soon(self.switch)

    def run(self):
        if self._target:
            self._target(*self._args, **self._kwargs)

    def join(self, timeout=None):
        """Wait for this Task to end. If a timeout is given, after the time expires the function
        will return anyway."""
        if not self._started:
            raise RuntimeError('cannot join task before it is started')
        return self._exit_event.wait(timeout)

    def kill(self, typ=TaskExit, value=None, tb=None):
        """Terminates the current task by raising an exception into it.
        Whatever that task might be doing; be it waiting for I/O or another
        primitive, it sees an exception as soon as it yields control.

        By default, this exception is TaskExit, but a specific exception
        may be specified.
        """
        if not self.is_alive():
            return
        if not value:
            value = typ()
        if not self._running:
            # task hasn't started yet and therefore throw won't work
            def just_raise():
                six.reraise(typ, value, tb)

            self.run = just_raise
            return
        evergreen.current.loop.call_soon(self.throw, typ, value, tb)

    def __repr__(self):
        status = "initial"
        if self._started:
            status = "started"
        if self._running:
            status = "running"
        if self._exit_event.is_set():
            status = "ended"
        return "<%s(%s, %s)>" % (self.__class__.__name__, self._name, status)

    @property
    def name(self):
        return self._name

    # internal

    def __run(self):
        try:
            self._running = True
            self.run()
        except TaskExit:
            pass
        finally:
            self._running = False
            del self._target, self._args, self._kwargs
            self._exit_event.set()
Ejemplo n.º 7
0
class Task(Fiber):

    def __init__(self, target=None, name=None, args=(), kwargs={}):
        super(Task, self).__init__(target=self.__run, parent=evergreen.current.loop.task)
        self._name = str(name or _newname())
        self._target = target
        self._args = args
        self._kwargs = kwargs
        self._started = False
        self._running = False
        self._exit_event = Event()

    def start(self):
        if self._started:
            raise RuntimeError('tasks can only be started once')
        self._started = True
        evergreen.current.loop.call_soon(self.switch)

    def run(self):
        if self._target:
            self._target(*self._args, **self._kwargs)

    def join(self, timeout=None):
        """Wait for this Task to end. If a timeout is given, after the time expires the function
        will return anyway."""
        if not self._started:
            raise RuntimeError('cannot join task before it is started')
        return self._exit_event.wait(timeout)

    def kill(self, typ=TaskExit, value=None, tb=None):
        """Terminates the current task by raising an exception into it.
        Whatever that task might be doing; be it waiting for I/O or another
        primitive, it sees an exception as soon as it yields control.

        By default, this exception is TaskExit, but a specific exception
        may be specified.
        """
        if not self.is_alive():
            return
        if not value:
            value = typ()
        if not self._running:
            # task hasn't started yet and therefore throw won't work
            def just_raise():
                six.reraise(typ, value, tb)
            self.run = just_raise
            return
        evergreen.current.loop.call_soon(self.throw, typ, value, tb)

    def __repr__(self):
        status = "initial"
        if self._started:
            status = "started"
        if self._running:
            status = "running"
        if self._exit_event.is_set():
            status = "ended"
        return "<%s(%s, %s)>" % (self.__class__.__name__, self._name, status)

    @property
    def name(self):
        return self._name

    # internal

    def __run(self):
        try:
            self._running = True
            self.run()
        except TaskExit:
            pass
        finally:
            self._running = False
            del self._target, self._args, self._kwargs
            self._exit_event.set()
Ejemplo n.º 8
0
class Task(tasklet):

    def __init__(self, target=None, name=None, args=(), kwargs={}):
        super(Task, self).__init__(parent=evergreen.current.loop.tasklet)
        self._name = str(name or _newname())
        self._target = target
        self._args = args
        self._kwargs = kwargs
        self._started = False
        self._exit_event = Event()

    def start(self):
        if self._started:
            raise RuntimeError('tasks can only be started once')
        self._started = True
        evergreen.current.loop.call_soon(self.switch)

    def run_(self):
        if self._target:
            self._target(*self._args, **self._kwargs)

    def join(self, timeout=None):
        """Wait for this Task to end. If a timeout is given, after the time expires the function
        will return anyway."""
        return self._exit_event.wait(timeout)

    def kill(self, *throw_args):
        """Terminates the current task by raising an exception into it.
        Whatever that task might be doing; be it waiting for I/O or another
        primitive, it sees an exception as soon as it yields control.

        By default, this exception is TaskExit, but a specific exception
        may be specified.  *throw_args* should be the same as the arguments to
        raise; either an exception instance or an exc_info tuple.

        """
        if self.dead:
            return
        if not self:
            # task hasn't started yet and therefore throw won't work
            def just_raise(*a, **kw):
                try:
                    if throw_args:
                        six.reraise(throw_args[0], throw_args[1], throw_args[2])
                    else:
                        raise TaskExit()
                finally:
                    self._exit_event.set()
            self.run_ = just_raise
            return
        evergreen.current.loop.call_soon(self.throw, *throw_args)

    def __repr__(self):
        status = "initial"
        if self._started:
            status = "started"
        if self.dead:
            status = "dead"
        if self._exit_event.is_set():
            status = "ended"
        return "<%s(%s, %s)>" % (self.__class__.__name__, self._name, status)

    @property
    def name(self):
        return self._name

    # internal

    def switch(self, *args, **kwargs):
        current = evergreen.current.task
        if current is not evergreen.current.loop.tasklet:
            raise RuntimeError('only the loop tasklet can switch to a Task')
        return super(Task, self).switch(*args, **kwargs)

    def throw(self, *args):
        current = evergreen.current.task
        if current is not evergreen.current.loop.tasklet:
            raise RuntimeError('only the loop tasklet can throw to a Task')
        return super(Task, self).throw(*args)

    def run(self):
        try:
            self.run_()
        finally:
            del self._target, self._args, self._kwargs
            self._exit_event.set()