基于python的延时队列
import threading
import functools
import queue
import datetime
def test():
print("执行成功")
def seconds_chagne(dt):
return dt.seconds + dt.days * 24 * 60 * 60
class DelayTask:
def __init__(self,delay_time,job_func):
self.delay_time = delay_time
self.job_func = job_func
class DelayQueue(queue.PriorityQueue):
def __init__(self):
self.can_done = threading.Condition()
super(DelayQueue, self).__init__()
def task_put(self,task):
self.put((task.delay_time,task))
def _peek(self):
self.not_empty.acquire()
try:
while not self._qsize():
self.not_empty.wait()
return self.queue[0][1]
finally:
self.not_empty.release()
def get_task(self):
self.can_done.acquire()
try:
task = self._peek()
delta = seconds_chagne(task.delay_time - datetime.datetime.now())
while delta > 0:
self.can_done.acquire(delta)
task = self._peek()
delta = seconds_chagne(task.delay_time - datetime.datetime.now())
item = self.get()
self.can_done.notify_all()
return item[1]
finally:
self.can_done.release()
task = functools.partial(test)
task_delay = DelayTask(delay_time=datetime.datetime.now()+datetime.timedelta(seconds=3),job_func=task)
delay_queue = DelayQueue()
delay_queue.task_put(task_delay)
res = delay_queue.get_task()
res.job_func()
基于redis写的延时队列(有序集合)
import redis
class DelayRedisQueue:
def __init__(self,key):
self.key = key
self.r = redis.Redis(decode_responses=True)
def add(self,uid,delay_time=0):
print("延时队列入队,%s秒后执行删除uid%s的任务" % (delay_time,uid))
self.r.zadd(self.key,{uid:time.time()+delay_time})
def remove(self,uid):
return self.r.zrem(self.key,uid)
def pop(self):
min_score = 0
max_score = time.time()
res = self.r.zrangebyscore(self.key,min_score,max_score,start=0,num=1,withscores=False)
if res == None:
print("暂无延时任务")
return False
if len(res) == 1:
print("延时任务到期,返回执行任务的uid%s"% res[0])
return res[0]
else:
print("延时任务没有到时间")
return False