|
@@ -0,0 +1,77 @@
|
|
|
+import heapq
|
|
|
+import time
|
|
|
+
|
|
|
+
|
|
|
+class Scheduler(object):
|
|
|
+
|
|
|
+ def __init__(self, bucket_queue):
|
|
|
+ self.bucket_queue = bucket_queue
|
|
|
+ self._queue = []
|
|
|
+
|
|
|
+ def enter(self, item, eta=None, priority=0, callback=None):
|
|
|
+ eta = time.mktime(eta.timetuple()) if eta else time.time()
|
|
|
+ heapq.heappush(self._queue, (eta, priority, item, callback))
|
|
|
+
|
|
|
+ def __iter__(self):
|
|
|
+ """The iterator yields the time to sleep for between runs."""
|
|
|
+
|
|
|
+ # localize variable access
|
|
|
+ q = self._queue
|
|
|
+ nowfun = time.time
|
|
|
+ pop = heapq.heappop
|
|
|
+ bucket = self.bucket_queue
|
|
|
+
|
|
|
+ while True:
|
|
|
+ if q:
|
|
|
+ eta, priority, item, callback = verify = q[0]
|
|
|
+ now = nowfun()
|
|
|
+
|
|
|
+ if now < eta:
|
|
|
+ yield eta - now
|
|
|
+ else:
|
|
|
+ event = pop(q)
|
|
|
+ print("eta->%s priority->%s item->%s" % (
|
|
|
+ eta, priority, item))
|
|
|
+
|
|
|
+ if event is verify:
|
|
|
+ bucket.put(item)
|
|
|
+ callback and callback()
|
|
|
+ yield 0
|
|
|
+ else:
|
|
|
+ heapq.heappush(q, event)
|
|
|
+ yield 1
|
|
|
+
|
|
|
+ def empty(self):
|
|
|
+ return not self._queue
|
|
|
+
|
|
|
+ @property
|
|
|
+ def queue(self):
|
|
|
+ events = list(self._queue)
|
|
|
+ return map(heapq.heappop, [events]*len(events))
|
|
|
+
|
|
|
+
|
|
|
+if __name__ == "__main__":
|
|
|
+ from Queue import Queue, Empty
|
|
|
+ from datetime import datetime, timedelta
|
|
|
+
|
|
|
+ bucket = Queue()
|
|
|
+ schedule = Scheduler(bucket)
|
|
|
+
|
|
|
+ # Enter some eta tasks in the scheduler
|
|
|
+ for i in reversed(range(10)):
|
|
|
+ task = "Task %d" % i
|
|
|
+ schedule.enter(task, eta=datetime.now() + timedelta(seconds=i + 5))
|
|
|
+
|
|
|
+ # Run the scheduler
|
|
|
+ for delay in schedule:
|
|
|
+ print("delay->%d" % delay)
|
|
|
+ if schedule.empty():
|
|
|
+ break
|
|
|
+ time.sleep(delay)
|
|
|
+
|
|
|
+ # Dump out the contents of the bucket queue.
|
|
|
+ while True:
|
|
|
+ try:
|
|
|
+ print(bucket.get_nowait())
|
|
|
+ except Empty:
|
|
|
+ break
|