import heapq import time import threading import Queue class Sched: def __init__(self): self.heap = [] self.running = True self.wait_event = threading.Event() def add(self, delay, queue): """Add new execution queue""" heapq.heappush(self.heap, (time.time() + delay, delay, queue)) self.wait_event.set() def stop(self): self.running = False self.wait_event.set() def tasks(self): """Produce events until stopped""" self.running = True while self.running: self.wait_event.clear() runtime, delay, queue = checked_event = self.heap[0] now = time.time() if now < runtime: self.wait(runtime) else : runtime, delay, queue = event = heapq.heappop(self.heap) # assure event was not removed or altered after last look at self.heap[0] if event is checked_event: try : task = queue.get_nowait() except Queue.Empty: pass #XXX else : yield task self.add(delay, queue) def wait(self, timestamp): """Wait until time, may return earlier if internal event occurs (stop, add)""" self.wait_event.wait(timestamp - time.time()) self.wait_event.clear() if __name__ == '__main__': s = Sched() one_sec_q = Queue.Queue() one_sec_q.put('foo') one_sec_q.put('bar') s.add(1, one_sec_q) five_sec_q = Queue.Queue() five_sec_q.put('baz') s.add(5, five_sec_q) print time.time() for value in s.tasks(): print time.time(), value