Welcome, guest | Sign In | My Account | Store | Cart

This class will run a timer that checks a Queue.Queue object at a given interval. This is useful for monitoring messages between threads. You give it a callback, interval, and it does the rest: When its finds a message, your callback is fired up.

Python, 102 lines
  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
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
import threading,Queue

class QueueMinder(object):
    
    def __init__(self, msgQueue, inCallback=None, interval=1.0, doStart=False):
        object.__init__(self)
        self.msgQueue = msgQueue
        if not inCallback: self.inCallback=self.gotMessage
        else: self.inCallback=inCallback
        self.interval = interval
        self.progressTimer = None
        if doStart:
            self.startTimer()

    def startTimer(self):
        self.progressTimer = threading.Timer(self.interval, self._progressCheck)
        self.progressTimer.start()

    def stopTimer(self):
        if self.progressTimer: self.progressTimer.cancel()
        self.progressTimer=None

    def gotMessage(self,msg):
        print 'gotMessage(): msg=%s'%msg

    def _progressCheck(self):
        try:
            while 1:
                msg = self.msgQueue.get(False)
                if msg: self.inCallback(msg)
        except Queue.Empty:
            self.startTimer()

from qt import *
class QtQueueMinder(QueueMinder, QObject):
    
    def __init__(self, msgQueue, inCallback=None, freq=500):
         QObject.__init__(self)
        # the interval is in milliseconds
        QueueMinder.__init__(self, msgQueue, inCallback, freq)

    def startTimer(self):
        if not self.progressTimer:
            self.progressTimer = QTimer()
            self.connect(self.progressTimer, SIGNAL("timeout()"), self._progressCheck)
            self.progressTimer.start(self.interval)

    def stopTimer(self):
        if self.progressTimer: self.progressTimer.stop()
        self.progressTimer=None

from Foundation import NSTimer
class MacQueueMinder(QueueMinder):
    def runTimer(target, selector, interval):
        return NSTimer.scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_(interval,target,selector,None,True)
    runTimer = staticmethod(runTimer)
    
    def __init__(self, msgQueue, inCallback=None, freq=0.5):
        # the interval is in seconds
        QueueMinder.__init__(self, msgQueue, inCallback, freq)
        return self

    def startTimer(self):
        self.progressTimer = MacQueueMinder.runTimer(self, 'progressCheck:', self.interval)
        self.progressTimer.retain()

    def stopTimer(self):
        if self.progressTimer:
            self.progressTimer.invalidate()
            self.progressTimer.autorelease()
            self.progressTimer = None

    def progressCheck_(self,timer=None):
        try:
            while 1:
                msg = self.msgQueue.get(False)
                if msg: self.inCallback(msg)
        except Queue.Empty:
	    pass

if __name__=='__main__':

    theQueue = Queue.Queue()

    class MyThread(threading.Thread):
        def __init__(self):
            threading.Thread.__init__(self)
            self.qm =None
            self.itsAllGood = True
            self.start()

        def run(self):
            self.qm=QueueMinder(theQueue)
            self.qm.startTimer()
            while self.itsAllGood:
                pass

    tt = MyThread()
    theQueue.put('How yall doin')
    theQueue.put('Everybody say hey')
    theQueue.put('Everybody say ho')
    tt.itsAllGood = False

My important threads need to talk to each other, so this little abstraction comes in handy for facilitacting inter-thread communication. Note that if your calling thread was using Qt, you'd need to replace the threading.Timer with a QTimer for this to work.

UPDATE: Added subclass examples for Qt and pyobjc for Mac OS X. Each of these frameworks uses a different timer class and different methods (for instance, the interval for Qt is milliseconds, and for NSTimer its seconds). Note the code above won't compile unless you have Qt and Foundation modules present. The 2 new classes are provided as an illustration.

1 comment

tuco Leone 18 years, 5 months ago  # | flag

Optional Syntax In QueueMinder's Class Constructor. <p> Sometimes an if/else can be replaced with an 'or' for prettyness. </p>

...
if not inCallback: self.inCallback=self.gotMessage
else: self.inCallback=inCallback
...

self.inCallback = inCallback or self.gotMessage
Created by Jonathan Kolyer on Thu, 26 May 2005 (PSF)
Python recipes (4591)
Jonathan Kolyer's recipes (6)

Required Modules

  • (none specified)

Other Information and Tasks