scheduler.py

changeset 76
4b08fca3ce34
parent 75
2a44b9649212
child 78
83b43987e61e
--- a/scheduler.py	Sat Jan 27 12:19:39 2018 +0000
+++ b/scheduler.py	Sun Jan 28 00:11:18 2018 +0000
@@ -6,6 +6,7 @@
 
 import time
 import borgend
+import sleep
 from threading import Condition, Lock, Thread
 
 logger=borgend.logger.getChild(__name__)
@@ -45,8 +46,11 @@
             n.prev=p
         if p:
             p.next=n
+        self.next=None
+        self.prev=None
 
 class ScheduledEvent(QueuedEvent):
+    #@accepts(ScheduledEvent, sleep.Time, threading.Cond, str)
     def __init__(self, when, cond, name=None):
         super().__init__(cond, name=name)
         self.when=when
@@ -90,6 +94,16 @@
             self._list=ev.next
         ev.unlink()
 
+    def _resort(self):
+        oldlist=self._list
+        self._list=None
+        while oldlist:
+            ev=oldlist
+            oldlist=oldlist.next
+            ev.unlink()
+            self._insert(ev)
+
+
 
 class Scheduler(QueueThread):
     # Default to precision of 60 seconds: the scheduler thread will never
@@ -99,6 +113,7 @@
         self.precision = precision
         self._next_event_time = None
         super().__init__(target = self._scheduler_thread, name = 'Scheduler')
+        sleep.add_callback(self, self._wakeup_callback)
 
     def _scheduler_thread(self):
         logger.debug("Scheduler thread started")
@@ -110,7 +125,7 @@
                 else:
                     # Wait at most precision seconds, or until next event if it
                     # comes earlier
-                    timeout=min(self.precision, self._list.when-now)
+                    timeout=min(self.precision, self._list.when.realtime()-now)
 
                 if not timeout or timeout>0:
                     logger.debug("Scheduler waiting %d seconds" % (timeout or (-1)))
@@ -119,7 +134,7 @@
 
                 logger.debug("Scheduler timed out")
 
-                while self._list and self._list.when <= now:
+                while self._list and self._list.when.monotonic() <= now:
                     ev=self._list
                     logger.debug("Scheduler activating %s" % (ev.name or "(unknown)"))
                     # We are only allowed to remove ev from list when ev.cond allows
@@ -128,6 +143,11 @@
                         ev.unlink()
                         ev.cond.notifyAll()
 
+    def _wakeup_callback(self):
+        logger.debug("Rescheduling events after wakeup")
+        with self._cond:
+            self._resort()
+
     def _wait(self, ev):
         with self._cond:
             self._insert(ev)
@@ -143,6 +163,7 @@
 
     # cond has to be acquired on entry!
     def wait_until(self, when, cond, name=None):
-        logger.debug("Scheduling '%s' at %d" % (name, when))
+        logger.debug("Scheduling '%s' in %s seconds [%s]" %
+                     (name, when.seconds_to(), when.__class__.__name__))
         self._wait(ScheduledEvent(when, cond, name))
 

mercurial