pope (owner)

Revisions

gist: 104795 Download_button fork
public
Public Clone URL: git://gist.github.com/104795.git
Embed All Files: show embed
periodic_reactor.py #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import time
import bisect
 
class PeriodicExecutor(object):#{{{
 
    def __init__(self, secs, callable):
        self.callable = callable
        self.secs = secs
        self.next_time_to_run = time.time()
 
    def __call__(self):
        self.next_time_to_run = time.time() + self.secs
        self.callable()
 
    def __cmp__(self, other):
        return cmp(self.next_time_to_run, other.next_time_to_run)
#}}}
 
class PeriodicReactor(object):#{{{
 
    def __init__(self):
        self.executors = []
 
    def add_periodic_executor(self, secs, callable):
        # keep the list sorted by time to execute, the earliest time first
        bisect.insort(self.executors, PeriodicExecutor(secs, callable))
 
    def __call__(self):
        while True and len(self.executors) != 0:
            # if the first element isn't ready to execute, then none of them
            # are ready
            while time.time() >= self.executors[0].next_time_to_run:
                executor = self.executors.pop(0)
                executor()
                # The time to execute has been reset, now add it back in
                bisect.insort(self.executors, executor)
            time.sleep(self.executors[0].next_time_to_run - time.time())
#}}}
 
if __name__ == "__main__":
    def printA():
        print "A"
 
    def printB():
        print "B"
 
    r = PeriodicReactor()
    r.add_periodic_executor(3, printA)
    r.add_periodic_executor(5, printB)
    r()