[英]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()
參數。 score
和data
的順序被切換。 以下是 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.