Exemple #1
0
    def test_priorityqueue_peek(self):
        """Peek at first element in queue"""

        p = PriorityQueue()

        self.assertRaises(IndexError, p.peek)
        p.enqueue(42)
        assert p.peek() == 42
        p.enqueue(41)
        assert p.peek() == 41
        p.enqueue(43)
        assert p.peek() == 41
Exemple #2
0
    def test_priorityqueue_peek(self):
        """Peek at first element in queue"""

        p = PriorityQueue()

        self.assertRaises(IndexError, p.peek)
        p.enqueue(42)
        assert(p.peek() == 42)
        p.enqueue(41)
        assert(p.peek() == 41)
        p.enqueue(43)
        assert(p.peek() == 41)
Exemple #3
0
    def test_priorityqueue_peek(self):
        """Peek at first element in queue"""

        p = PriorityQueue()

        self.assertRaises(InvalidOperationException, p.peek)
        p.enqueue(42)
        assert p.peek() == 42
        p.enqueue(41)
        assert p.peek() == 41
        p.enqueue(43)
        assert p.peek() == 41
class VirtualTimeScheduler(Scheduler):
    """Virtual Scheduler. This scheduler should work with either
    datetime/timespan or ticks as int/int"""

    def __init__(self, initial_clock=0, comparer=None):
        """Creates a new virtual time scheduler with the specified initial
        clock value and absolute time comparer.

        Keyword arguments:
        initial_clock -- Initial value for the clock.
        comparer -- Comparer to determine causality of events based on absolute time.
        """

        self.clock = initial_clock
        self.comparer = comparer
        self.is_enabled = False
        self.queue = PriorityQueue(1024)

        super(VirtualTimeScheduler, self).__init__()

    def local_now(self):
        return self.to_datetime(self.clock)

    def schedule_now(self, state, action):
        return self.schedule_absolute_with_state(state, self.clock, action)

    def now(self):
        """Gets the scheduler's absolute time clock value as datetime offset."""

        return self.to_datetime(self.clock)

    def schedule(self, action, state=None):
        return self.schedule_absolute(self.clock, action, state)

    def schedule_relative(self, duetime, action, state=None):
        """Schedules an action to be executed at duetime. Return the disposable
        object used to cancel the scheduled action (best effort)

        Keyword arguments:
        due_time -- Relative time after which to execute the action.
        action -- Action to be executed.
        state -- [Optional] State passed to the action to be executed.
        """
        log.debug("VirtualTimeScheduler.schedule_relative(duetime=%s, state=%s)" % (duetime, state))

        runat = self.add(self.clock, self.to_relative(duetime))
        return self.schedule_absolute(duetime=runat, action=action, state=state)

    def schedule_absolute(self, duetime, action, state=None):
        """Schedules an action to be executed at duetime."""

        def run(scheduler, state1):
            self.queue.remove(si)

            return action(scheduler, state1)

        si = ScheduledItem(self, state, run, duetime, self.comparer)
        self.queue.enqueue(si)
        return si.disposable

    def schedule_periodic(self, period, action, state=None):
        scheduler = SchedulePeriodicRecursive(self, period, action, state)
        return scheduler.start()

    def start(self):
        """Starts the virtual time scheduler."""
        next = None
        if not self.is_enabled:
            self.is_enabled = True
            while self.is_enabled:
                next = self.get_next()
                if next:
                    if self.comparer(next.duetime, self.clock) > 0:
                        self.clock = next.duetime
                        log.info("VirtualTimeScheduler.start(), clock: %s",
                                 self.clock)
                    next.invoke()
                else:
                    self.is_enabled = False

    def stop(self):
        """Stops the virtual time scheduler."""
        self.is_enabled = False

    def advance_to(self, time):
        """Advances the scheduler's clock to the specified time, running all
        work til that point.

        Keyword arguments:
        time -- Absolute time to advance the scheduler's clock to.
        """
        next = None

        due_to_clock = self.comparer(self.clock, time)
        if due_to_clock > 0:
            raise ArgumentOutOfRangeException()

        if not due_to_clock:
            return

        if not self.is_enabled:
            self.is_enabled = True
            while self.is_enabled:
                next = self.get_next()
                if next and self.comparer(next.duetime, time) <= 0:
                    if self.comparer(next.duetime, self.clock) > 0:
                        self.clock = next.duetime

                    next.invoke()
                else:
                    self.is_enabled = False

            self.clock = time

    def advance_by(self, time):
        """Advances the scheduler's clock by the specified relative time,
        running all work scheduled for that timespan.

        Keyword arguments:
        time -- Relative time to advance the scheduler's clock by.
        """
        log.debug("VirtualTimeScheduler.advance_by(time=%s)", time)

        dt = self.add(self.clock, time)
        if self.comparer(self.clock, dt) > 0:
            raise ArgumentOutOfRangeException()
        return self.advance_to(dt)

    def sleep(self, time):
        """Advances the scheduler's clock by the specified relative time.

        Keyword arguments:
        time -- Relative time to advance the scheduler's clock by.
        """
        dt = self.add(self.clock, time)

        if self.comparer(self.clock, dt) >= 0:
            raise ArgumentOutOfRangeException()

        self.clock = dt

    def get_next(self):
        """Returns the next scheduled item to be executed."""
        while self.queue.length > 0:
            next = self.queue.peek()
            if next.is_cancelled():
                self.queue.dequeue()
            else:
                return next

        return None

    def add(self, absolute, relative):
        raise NotImplementedError
Exemple #5
0
class PyGameScheduler(Scheduler):
    """A scheduler that schedules works for PyGame.

    http://www.pygame.org/docs/ref/time.html
    http://www.pygame.org/docs/ref/event.html"""
    def __init__(self, event_id=None):
        global pygame
        import pygame

        self.timer = None
        self.event_id = event_id or pygame.USEREVENT

        self.queue = PriorityQueue()

    def schedule(self, action, state=None):
        """Schedules an action to be executed."""

        log.debug("PyGameScheduler.schedule(state=%s)", state)
        return self.schedule_relative(0, action, state)

    def run(self):
        while self.queue.length:
            item = self.queue.peek()
            diff = item.duetime - self.now()
            if diff > timedelta(0):
                break

            item = self.queue.dequeue()
            if not item.is_cancelled():
                item.invoke()

    def schedule_relative(self, duetime, action, state=None):
        """Schedules an action to be executed after duetime.

        Keyword arguments:
        duetime -- {timedelta} Relative time after which to execute the action.
        action -- {Function} Action to be executed.

        Returns {Disposable} The disposable object used to cancel the scheduled
        action (best effort)."""

        dt = self.now() + self.to_timedelta(duetime)
        si = ScheduledItem(self, state, action, dt)

        self.queue.enqueue(si)

        return si.disposable

    def schedule_absolute(self, duetime, action, state=None):
        """Schedules an action to be executed at duetime.

        Keyword arguments:
        duetime -- {datetime} Absolute time after which to execute the action.
        action -- {Function} Action to be executed.

        Returns {Disposable} The disposable object used to cancel the scheduled
        action (best effort)."""

        return self.schedule_relative(duetime - self.now(), action, state)

    def now(self):
        """Represents a notion of time for this scheduler. Tasks being scheduled
        on a scheduler will adhere to the time denoted by this property."""

        return self.to_datetime(pygame.time.get_ticks())
Exemple #6
0
class PyGameScheduler(Scheduler):
    """A scheduler that schedules works for PyGame.

    http://www.pygame.org/docs/ref/time.html
    http://www.pygame.org/docs/ref/event.html"""

    def __init__(self, event_id=None):
        global pygame
        import pygame

        self.timer = None
        self.event_id = event_id or pygame.USEREVENT

        self.queue = PriorityQueue()

    def schedule(self, action, state=None):
        """Schedules an action to be executed."""

        log.debug("PyGameScheduler.schedule(state=%s)", state)
        return self.schedule_relative(0, action, state)

    def run(self):
        while len(self.queue):
            item = self.queue.peek()
            diff = item.duetime - self.now()
            if diff > timedelta(0):
                break

            item = self.queue.dequeue()
            if not item.is_cancelled():
                item.invoke()

    def schedule_relative(self, duetime, action, state=None):
        """Schedules an action to be executed after duetime.

        Keyword arguments:
        duetime -- {timedelta} Relative time after which to execute the action.
        action -- {Function} Action to be executed.

        Returns {Disposable} The disposable object used to cancel the scheduled
        action (best effort)."""

        dt = self.now() + self.to_timedelta(duetime)
        si = ScheduledItem(self, state, action, dt)

        self.queue.enqueue(si)

        return si.disposable

    def schedule_absolute(self, duetime, action, state=None):
        """Schedules an action to be executed at duetime.

        Keyword arguments:
        duetime -- {datetime} Absolute time after which to execute the action.
        action -- {Function} Action to be executed.

        Returns {Disposable} The disposable object used to cancel the scheduled
        action (best effort)."""

        return self.schedule_relative(duetime - self.now(), action, state)

    def now(self):
        """Represents a notion of time for this scheduler. Tasks being scheduled
        on a scheduler will adhere to the time denoted by this property."""

        return self.to_datetime(pygame.time.get_ticks())
class TrampolineScheduler(RxBPSchedulerBase, Scheduler):
    def __init__(self):
        """Gets a scheduler that schedules work as soon as possible on the
        current thread."""

        super().__init__()

        self._idle = True
        self.queue = PriorityQueue()

        self.lock = threading.RLock()

    def sleep(self, seconds: float) -> None:
        time.sleep(seconds)

    @property
    def idle(self) -> bool:
        return self._idle

    @property
    def is_order_guaranteed(self) -> bool:
        return True

    def schedule(self,
                 action: typing.ScheduledAction,
                 state: Optional[typing.TState] = None) -> typing.Disposable:
        """Schedules an action to be executed.
        Args:
            action: Action to be executed.
            state: [Optional] state to be given to the action function.
        Returns:
            The disposable object used to cancel the scheduled action
            (best effort).
        """

        return self.schedule_absolute(self.now, action, state=state)

    def schedule_relative(
            self,
            duetime: typing.RelativeTime,
            action: typing.ScheduledAction,
            state: Optional[typing.TState] = None) -> typing.Disposable:
        """Schedules an action to be executed after duetime.
        Args:
            duetime: Relative time after which to execute the action.
            action: Action to be executed.
            state: [Optional] state to be given to the action function.
        Returns:
            The disposable object used to cancel the scheduled action
            (best effort).
        """

        # duetime = SchedulerBase.normalize(self.to_timedelta(duetime))
        duetime = self.to_timedelta(duetime)
        return self.schedule_absolute(self.now + duetime, action, state=state)

    def schedule_absolute(
            self,
            duetime: typing.AbsoluteTime,
            action: typing.ScheduledAction,
            state: Optional[typing.TState] = None) -> typing.Disposable:
        """Schedules an action to be executed at duetime.
        Args:
            duetime: Absolute time after which to execute the action.
            action: Action to be executed.
            state: [Optional] state to be given to the action function.
        """

        duetime = self.to_datetime(duetime)

        if duetime > self.now:
            log.warning("Do not schedule imperative work!")

        si = ScheduledItem(self, state, action, duetime)

        with self.lock:
            self.queue.enqueue(si)

            if self._idle:
                self._idle = False
                start_trampoline = True
            else:
                start_trampoline = False

        if start_trampoline:
            while True:
                try:
                    while self.queue:
                        item: ScheduledItem = self.queue.peek()

                        if item.is_cancelled():
                            with self.lock:
                                self.queue.dequeue()

                        else:
                            diff = item.duetime - item.scheduler.now
                            if diff <= datetime.timedelta(0):
                                item.invoke()
                                with self.lock:
                                    self.queue.dequeue()
                            else:
                                time.sleep(diff.total_seconds())

                except:
                    traceback.print_exc()
                finally:
                    with self.lock:
                        if not self.queue:
                            self._idle = True
                            # self.queue.clear()
                            break

        return si.disposable
class PyGameScheduler(SchedulerBase):
    """A scheduler that schedules works for PyGame.

    http://www.pygame.org/docs/ref/time.html
    http://www.pygame.org/docs/ref/event.html"""

    def __init__(self, event_id=None):
        global pygame
        import pygame

        self.timer = None
        self.event_id = event_id or pygame.USEREVENT

        self.queue = PriorityQueue()

    def schedule(self, action: typing.ScheduledAction, state: Any = None) -> typing.Disposable:
        """Schedules an action to be executed."""

        log.debug("PyGameScheduler.schedule(state=%s)", state)
        return self.schedule_relative(0, action, state)

    def run(self) -> None:
        while self.queue:
            item = self.queue.peek()
            diff = item.duetime - self.now

            if diff > timedelta(0):
                break

            item = self.queue.dequeue()
            if not item.is_cancelled():
                item.invoke()

    def schedule_relative(self, duetime: typing.RelativeTime, action: typing.ScheduledAction,
                          state: typing.TState = None) -> typing.Disposable:
        """Schedules an action to be executed after duetime.

        Args:
            duetime: Relative time after which to execute the action.
            action: Action to be executed.

        Returns:
            The disposable object used to cancel the scheduled action
            (best effort).
        """

        dt = self.now + self.to_timedelta(duetime)
        si: ScheduledItem[typing.TState] = ScheduledItem(self, state, action, dt)

        self.queue.enqueue(si)

        return si.disposable

    def schedule_absolute(self, duetime: typing.AbsoluteTime, action: typing.ScheduledAction,
                          state: typing.TState = None) -> typing.Disposable:
        """Schedules an action to be executed at duetime.

        Args:
            duetime: Absolute time after which to execute the action.
            action: Action to be executed.

        Returns:
            The disposable object used to cancel the scheduled action
            (best effort)."""

        return self.schedule_relative(duetime - self.now, action, state)

    @property
    def now(self) -> datetime:
        """Represents a notion of time for this scheduler. Tasks being
        scheduled on a scheduler will adhere to the time denoted by
        this property."""

        return datetime.utcnow()
class VirtualTimeScheduler(Scheduler):
    """Virtual Scheduler. This scheduler should work with either
    datetime/timespan or ticks as int/int"""
    def __init__(self, initial_clock=0, comparer=None):
        """Creates a new virtual time scheduler with the specified initial
        clock value and absolute time comparer.

        Keyword arguments:
        initial_clock -- Initial value for the clock.
        comparer -- Comparer to determine causality of events based on absolute
            time."""

        self.clock = initial_clock

        self.comparer = comparer
        self.is_enabled = False
        self.queue = PriorityQueue(1024)

        super(VirtualTimeScheduler, self).__init__()

    def now(self):
        """Gets the schedulers absolute time clock value as datetime offset."""

        return self.to_datetime(self.clock)

    def schedule(self, action, state=None):
        """Schedules an action to be executed."""

        return self.schedule_absolute(self.clock, action, state)

    def schedule_relative(self, duetime, action, state=None):
        """Schedules an action to be executed at duetime. Return the disposable
        object used to cancel the scheduled action (best effort)

        Keyword arguments:
        duetime -- Relative time after which to execute the action.
        action -- Action to be executed.
        state -- [Optional] State passed to the action to be executed."""

        log.debug(
            "VirtualTimeScheduler.schedule_relative(duetime=%s, state=%s)" %
            (duetime, state))

        runat = self.add(self.clock, self.to_relative(duetime))
        return self.schedule_absolute(duetime=runat,
                                      action=action,
                                      state=state)

    def schedule_absolute(self, duetime, action, state=None):
        """Schedules an action to be executed at duetime."""
        def run(scheduler, state1):
            self.queue.remove(si)
            return action(scheduler, state1)

        si = ScheduledItem(self, state, run, duetime, self.comparer)
        self.queue.enqueue(si)
        return si.disposable

    def schedule_periodic(self, period, action, state=None):
        scheduler = SchedulePeriodicRecursive(self, period, action, state)
        return scheduler.start()

    def start(self):
        """Starts the virtual time scheduler."""

        if not self.is_enabled:
            self.is_enabled = True
            while self.is_enabled:
                next = self.get_next()
                if next:
                    if self.comparer(next.duetime, self.clock) > 0:
                        self.clock = next.duetime
                        log.info("VirtualTimeScheduler.start(), clock: %s",
                                 self.clock)
                    next.invoke()
                else:
                    self.is_enabled = False

    def stop(self):
        """Stops the virtual time scheduler."""

        self.is_enabled = False

    def advance_to(self, time):
        """Advances the schedulers clock to the specified time, running all
        work til that point.

        Keyword arguments:
        time -- Absolute time to advance the schedulers clock to."""

        due_to_clock = self.comparer(self.clock, time)
        if due_to_clock > 0:
            raise ArgumentOutOfRangeException()

        if not due_to_clock:
            return

        if not self.is_enabled:
            self.is_enabled = True
            while self.is_enabled:
                next = self.get_next()
                if next and self.comparer(next.duetime, time) <= 0:
                    if self.comparer(next.duetime, self.clock) > 0:
                        self.clock = next.duetime

                    next.invoke()
                else:
                    self.is_enabled = False

            self.clock = time

    def advance_by(self, time):
        """Advances the schedulers clock by the specified relative time,
        running all work scheduled for that timespan.

        Keyword arguments:
        time -- Relative time to advance the schedulers clock by."""

        log.debug("VirtualTimeScheduler.advance_by(time=%s)", time)

        dt = self.add(self.clock, time)
        if self.comparer(self.clock, dt) > 0:
            raise ArgumentOutOfRangeException()
        return self.advance_to(dt)

    def sleep(self, time):
        """Advances the schedulers clock by the specified relative time.

        Keyword arguments:
        time -- Relative time to advance the schedulers clock by."""

        dt = self.add(self.clock, time)

        if self.comparer(self.clock, dt) >= 0:
            raise ArgumentOutOfRangeException()

        self.clock = dt

    def get_next(self):
        """Returns the next scheduled item to be executed."""

        while len(self.queue):
            next = self.queue.peek()
            if next.is_cancelled():
                self.queue.dequeue()
            else:
                return next

        return None

    @staticmethod
    def add(absolute, relative):
        raise NotImplementedError
Exemple #10
0
class PyGameScheduler(SchedulerBase):
    """A scheduler that schedules works for PyGame.

    http://www.pygame.org/docs/ref/time.html
    http://www.pygame.org/docs/ref/event.html"""
    def __init__(self, event_id=None):
        global pygame
        import pygame

        self.timer = None
        self.event_id = event_id or pygame.USEREVENT

        self.queue = PriorityQueue()

    def schedule(self,
                 action: typing.ScheduledAction,
                 state: Any = None) -> typing.Disposable:
        """Schedules an action to be executed."""

        log.debug("PyGameScheduler.schedule(state=%s)", state)
        return self.schedule_relative(0, action, state)

    def run(self) -> None:
        while self.queue:
            item = self.queue.peek()
            diff = item.duetime - self.now

            if diff > timedelta(0):
                break

            item = self.queue.dequeue()
            if not item.is_cancelled():
                item.invoke()

    def schedule_relative(self,
                          duetime: typing.RelativeTime,
                          action: typing.ScheduledAction,
                          state: typing.TState = None) -> typing.Disposable:
        """Schedules an action to be executed after duetime.

        Args:
            duetime: Relative time after which to execute the action.
            action: Action to be executed.

        Returns:
            The disposable object used to cancel the scheduled action
            (best effort).
        """

        dt = self.now + self.to_timedelta(duetime)
        si: ScheduledItem[typing.TState] = ScheduledItem(
            self, state, action, dt)

        self.queue.enqueue(si)

        return si.disposable

    def schedule_absolute(self,
                          duetime: typing.AbsoluteTime,
                          action: typing.ScheduledAction,
                          state: typing.TState = None) -> typing.Disposable:
        """Schedules an action to be executed at duetime.

        Args:
            duetime: Absolute time after which to execute the action.
            action: Action to be executed.

        Returns:
            The disposable object used to cancel the scheduled action
            (best effort)."""

        return self.schedule_relative(duetime - self.now, action, state)

    @property
    def now(self) -> datetime:
        """Represents a notion of time for this scheduler. Tasks being
        scheduled on a scheduler will adhere to the time denoted by
        this property."""

        return datetime.utcnow()
class VirtualTimeScheduler(Scheduler):
    """Virtual Scheduler"""
    def __init__(self, initial_clock=0, comparer=None):
        """Creates a new virtual time scheduler with the specified initial 
        clock value and absolute time comparer.
        
        Keyword arguments:
        initial_clock -- Initial value for the clock.
        comparer -- Comparer to determine causality of events based on absolute time.
        """

        self.clock = initial_clock
        self.comparer = comparer
        self.is_enabled = False
        self.queue = PriorityQueue(1024)

    def now(self):
        #return self.clock
        return self.to_datetime_offset(self.clock)

    def schedule(self, action, state=None):
        return self.schedule_absolute(self.clock, action, state)

    def schedule_relative(self, duetime, action, state=None):
        """Schedules an action to be executed at duetime. Return the disposable
        object used to cancel the scheduled action (best effort)

        Keyword arguments:
        due_time -- Relative time after which to execute the action.
        action -- Action to be executed.
        state -- [Optional] State passed to the action to be executed.
        """
        log.debug(
            "VirtualTimeScheduler.schedule_relative(duetime=%s, state=%s)" %
            (duetime, state))

        runat = self.add(self.clock, self.to_relative(duetime))
        return self.schedule_absolute(runat, action, state)

    def schedule_absolute(self, duetime, action, state=None):
        log.debug(
            "VirtualTimeScheduler.schedule_absolute(duetime=%s, state=%s)" %
            (duetime, state))

        def run(scheduler, state1):
            #print ("VirtualTimeScheduler:schedule_absolute:run(%s)" % repr(state1))
            self.queue.remove(si)

            #print ("running action", action.__doc__)
            return action(scheduler, state1)

        si = ScheduledItem(self, state, run, duetime, self.comparer)
        self.queue.enqueue(si)
        return si.disposable

    def schedule_periodic(self, period, action, state=None):
        scheduler = SchedulePeriodicRecursive(self, period, action, state)
        return scheduler.start()

    def start(self):
        """Starts the virtual time scheduler."""
        next = None
        if not self.is_enabled:
            self.is_enabled = True
            while self.is_enabled:
                #print (self.clock)
                next = self.get_next()
                if next:
                    if self.comparer(next.duetime, self.clock) > 0:
                        self.clock = next.duetime
                        log.info("VirtualTimeScheduler.start(), clock: %s" %
                                 self.clock)
                    #else:
                    #    print ("skipping", next.duetime, self.clock)

                    #print ("Invoke: ", self.clock, next.action)
                    next.invoke()
                else:
                    self.is_enabled = False

    def stop(self):
        """Stops the virtual time scheduler."""
        self.is_enabled = False

    def advance_to(self, time):
        """Advances the scheduler's clock to the specified time, running all 
        work till that point.
        
        Keyword arguments:
        time -- Absolute time to advance the scheduler's clock to.
        """
        print("advance_to()")
        next = None
        if self.comparer(self.clock, time) >= 0:
            raise ArgumentOutOfRangeException()

        if not self.is_enabled:
            self.is_enabled = True
            while self.is_enabled:
                next = self.get_next()
                if next and self.comparer(next.duetime, time) <= 0:
                    if self.comparer(next.duetime, self.clock) > 0:
                        self.clock = next.duetime

                    next.invoke()
                else:
                    self.is_enabled = False

            self.clock = time

    def advance_by(self, time):
        """Advances the scheduler's clock by the specified relative time, 
        running all work scheduled for that timespan.
        
        Keyword arguments:
        time -- Relative time to advance the scheduler's clock by.
        """
        log.debug("VirtualTimeScheduler.advance_by(time=%s)" % time)

        dt = self.add(self.clock, time)
        if self.comparer(self.clock, dt) >= 0:
            raise ArgumentOutOfRangeException()

        return self.advance_to(dt)

    def sleep(self, time):
        """Advances the scheduler's clock by the specified relative time.

        Keyword arguments:
        time -- Relative time to advance the scheduler's clock by.
        """
        dt = self.add(self.clock, time)

        if self.comparer(self.clock, dt) >= 0:
            raise ArgumentOutOfRangeException()

        self.clock = dt

    def get_next(self):
        """Returns the next scheduled item to be executed."""
        while self.queue.length > 0:
            next = self.queue.peek()
            if next.is_cancelled():
                self.queue.dequeue()
            else:
                return next

        return None