]> code.delx.au - bg-scripts/blobdiff - asyncsched.py
Removed the bin/ and lib/ directories... Now everything is in a single directory
[bg-scripts] / asyncsched.py
diff --git a/asyncsched.py b/asyncsched.py
new file mode 100644 (file)
index 0000000..428fcf3
--- /dev/null
@@ -0,0 +1,60 @@
+# Copyright 2008 James Bunton <jamesbunton@fastmail.fm>
+# Licensed for distribution under the GPL version 2, check COPYING for details
+# asyncore.loop() with delayed function calls
+
+import asyncore
+import heapq
+import signal
+import time
+
+tasks = []
+running = False
+
+class Task(object):
+       def __init__(self, delay, func, args=[], kwargs={}):
+               self.time = time.time() + delay
+               self.func = lambda: func(*args, **kwargs)
+       
+       def __cmp__(self, other):
+               return cmp(self.time, other.time)
+
+       def __call__(self):
+               f = self.func
+               self.func = None
+               if f:
+                       return f()
+
+       def cancel(self):
+               assert self.func is not None
+               self.func = None
+
+def schedule(delay, func, args=[], kwargs={}):
+       task = Task(delay, func, args, kwargs)
+       heapq.heappush(tasks, task)
+       return task
+
+def loop(timeout=30.0, use_poll=False):
+       global running
+       running = True
+       oldhandler = signal.signal(signal.SIGTERM, exit)
+
+       while running:
+               now = time.time()
+               while tasks and tasks[0].time < now:
+                       task = heapq.heappop(tasks)
+                       task()
+
+               t = timeout
+               if tasks:
+                       t = max(min(t, tasks[0].time - now), 0)
+
+               asyncore.loop(timeout=t, count=1, use_poll=use_poll)
+       
+       signal.signal(signal.SIGTERM, oldhandler)
+
+def exit(*args):
+       global running
+       running = False
+
+__all__ = ("schedule", "loop", "exit")
+