Search code examples
pythonpython-2.7timerheappriority-queue

Python: priority queue with time as priority


I have a priority queue build using heaps. The queue contains messages, which should be send in the order regarding to the priority. However, as the priority value I have a time after which the message should be send, for example a set of messages which I have to put to the queue:

(10, message1)
(15, message2)
(5, message3)

So sending the messages following the priority is easy. However, if I will first send the messag3 after 5 seconds from putting it to the queue, I would like to make sure that the next message, message1, will be send 10 seconds after putting into the queue, what gives 5 seconds after message3 was send. Does anyone knows any examples how I can manage to do that?


Solution

  • You could use epoch as a priority value and every time timer fires calculate when it should fire again based on current time. Here's a short example of that in practice:

    import calendar
    import time
    import heapq
    from threading import Timer
    
    def epoch():
        return calendar.timegm(time.gmtime())
    
    start_time = epoch()
    heap = []
    timer = None
    
    def add_message(seconds, content):
        top = heap[0] if heap else None
        heapq.heappush(heap, (epoch() + seconds, content))
        if timer and top != heap[0]:
            timer.cancel()
            start()
    
    def start():
        global timer
        if heap:
            timer = Timer(heap[0][0] - epoch(), fire)
            timer.start()
    
    def fire():
        _, message = heapq.heappop(heap)
        print '{}: {}'.format(epoch() - start_time, message)
        start()
    
    add_message(10, 'message1')
    add_message(15, 'message2')
    add_message(5, 'message3')
    start()
    add_message(1, 'message4')
    

    Output:

    1: message4
    5: message3
    10: message1
    15: message2