簡體   English   中英

替代threading.Timer?

[英]Alternative of threading.Timer?

我有一個生產者-消費者模式Queue,它消耗傳入的事件並安排合格事件在5秒鍾內發送出去。 我正在使用threading.Timer() python文檔來執行此操作,並且一切正常。

最近,我被要求將計划時間從5秒更改為30分鍾,並且threading.Timer()我的腳本崩潰,因為以前創建並很快釋放了線程對象(僅持續5秒鍾),但是現在必須保留活了30分鍾

這是代碼:

 if scheduled_time and out_event:
     threading.Timer(scheduled_time, self.send_out_event, (socket_connection, received_event, out_event,)).start()  # schedule event send out

有人可以對此有所啟發嗎? 我該如何解決這個問題,或者threading.Timer()是否有其他選擇?

感謝@dano對第三方模塊的評論! 根據我的工作要求,我沒有將它們安裝在服務器上。

我選擇使用基於Redis的Delay Queue,而不是使用threading.Timer() ,而是在線找到了一些有用的資源: 一個獨特的基於Python Redis的delay隊列。 它解決了我的問題。

簡要地說,作者在redis中創建了一個排序集並為其命名, add()會將新數據追加到該排序集中。 每次根據epoc-time分數從排序集中最多彈出一個元素時,將彈出符合條件的最低得分的元素( 不從redis中刪除

def add(self, received_event, delay_queue_name="delay_queue", delay=config.SECOND_RETRY_DELAY):
    try:
        score = int(time.time()) + delay
        self.__client.zadd(delay_queue_name, score, received_event)
        self.__logger.debug("added {0} to delay queue, delay time:{1}".format(received_event, delay))
    except Exception as e:
        self.__logger.error("error: {0}".format(e))


def pop(self, delay_queue_name="delay_queue"):
    min_score, max_score, element = 0, int(time.time()), None

    try:
        result = self.__client.zrangebyscore(delay_queue_name, min_score, max_score, start=0, num=1, withscores=False)
    except Exception as e:
        self.__logger.error("failed query from redis:{0}".format(e))
        return None

    if result and len(result) == 1:
        element = result[0]
        self.__logger.debug("poped {0} from delay queue".format(element))
    else:
        self.__logger.debug("no qualified element")
    return element

def remove(self, element, delay_queue_name="delay_queue"):
    self.__client.zrem(delay_queue_name, element)

self.__client是Redis客戶端實例redis.StrictRedis(host=rhost,port=rport, db=rindex)

在線資源與我的在線資源之間的區別在於,我切換了zadd()參數。 scoredata的順序被切換。 以下是 zadd() 文檔

這是python redis doc:

# SORTED SET COMMANDS
def zadd(self, name, *args, **kwargs):
    """
    Set any number of score, element-name pairs to the key ``name``. Pairs
    can be specified in two ways:

    As *args, in the form of: score1, name1, score2, name2, ...
    or as **kwargs, in the form of: name1=score1, name2=score2, ...

    The following example would add four values to the 'my-key' key:
    redis.zadd('my-key', 1.1, 'name1', 2.2, 'name2', name3=3.3, name4=4.4)
    """
    pieces = []
    if args:
        if len(args) % 2 != 0:
            raise RedisError("ZADD requires an equal number of "
                             "values and scores")
        pieces.extend(args)
    for pair in iteritems(kwargs):
        pieces.append(pair[1])
        pieces.append(pair[0])
    return self.execute_command('ZADD', name, *pieces)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM