[英]Alternative of threading.Timer?
I have a producer-consumer pattern Queue, it consumes incoming events and schedule qualified events sending out in 5 seconds. 我有一个生产者-消费者模式Queue,它消耗传入的事件并安排合格事件在5秒钟内发送出去。 I am using
threading.Timer()
python document to do it and everything was working fine. 我正在使用
threading.Timer()
python文档来执行此操作,并且一切正常。
Recently, I was requested to change the scheduled time from 5 second to 30 minutes, and threading.Timer()
crashes my script because previously the threads objects are created and are released very soon(only last 5 sec) but now it has to keep alive for 30 minutes. 最近,我被要求将计划时间从5秒更改为30分钟,并且
threading.Timer()
我的脚本崩溃,因为以前创建并很快释放了线程对象(仅持续5秒钟),但是现在必须保留活了30分钟
Here's the code: 这是代码:
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
Can somesone shed some light on this? 有人可以对此有所启发吗? How can I solve this problem or is there any alternative for
threading.Timer()
? 我该如何解决这个问题,或者
threading.Timer()
是否有其他选择?
Thanks for @dano 's comment about the 3rd party modules! 感谢@dano对第三方模块的评论! Based on my work requirement, I didn't install them on the server.
根据我的工作要求,我没有将它们安装在服务器上。
Instead of using threading.Timer()
, I choose to use a Redis based Delay Queue, I found some helpful source online: A unique Python redis-based queue with delay . 我选择使用基于Redis的Delay Queue,而不是使用
threading.Timer()
,而是在线找到了一些有用的资源: 一个独特的基于Python Redis的delay队列。 It solved my issue. 它解决了我的问题。
Briefly, the author creates a sorted set in redis and give it a name, add()
would appends new data into the sorted set. 简要地说,作者在redis中创建了一个排序集并为其命名,
add()
会将新数据追加到该排序集中。 Every time it pops at most one element from the sorted set based upon the epoc-time score, the element which holds qualified minimum score would be pop out( Not remove from redis ) 每次根据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
is a Redis client instance, redis.StrictRedis(host=rhost,port=rport, db=rindex)
. self.__client
是Redis客户端实例redis.StrictRedis(host=rhost,port=rport, db=rindex)
。
The difference between the online source with mine is that I switched zadd()
parameters. 在线资源与我的在线资源之间的区别在于,我切换了
zadd()
参数。 The order of score
and data
are switched. score
和data
的顺序被切换。 Below is docs of zadd()
以下是
zadd()
文档
Here's the python redis doc: 这是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.