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
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)
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
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())
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
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