X-Git-Url: https://code.delx.au/bg-scripts/blobdiff_plain/f9c37d3e9223c407abe5775490b258fb8ad5bdac..1ad2850b8c0ec352f1d096882d961325604afd71:/asyncsched.py diff --git a/asyncsched.py b/asyncsched.py new file mode 100644 index 0000000..428fcf3 --- /dev/null +++ b/asyncsched.py @@ -0,0 +1,60 @@ +# Copyright 2008 James Bunton +# 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") +