是否可以在N秒后设置密钥的方法?

时间:2018-06-26 01:46:02

标签: python-3.x redis

我通过Python 3.6.1 :: Anaconda 4.4.0 (64-bit)redis-cli 3.2.100上使用Windows 10pip install redis==2.10.6

我知道有一种方法可以使用SETEX设置N秒后过期的密钥。

> SETEX s 10 "hi"
OK
> TTL s  # variable s still alive for 9 seconds
(integer) 9
> GET s
"hi"
> GET s  # ↑ within 10 seconds
"hi"     
> GET s  # ↓ 10 seconds later
(nil)

但是现在我需要一种可以在N秒后设置密钥的方法,例如SETAF,还需要一种可以在N秒后生成密钥的方法,例如AFTTL

> SETAF s 10 "hi"  # set s="hi" after 10 seconds
OK
> GET s
(nil)
> AFTTL s
(integer) 5
> GET s            # ↑ within 10 seconds
(nil)
> GET s            # ↓ 10 seconds later
"hi"

2 个答案:

答案 0 :(得分:2)

没有内置的方法可以做到这一点。我可以建议两种方法:

  1. 使用assume-unchanged在redis中设置一个虚拟计时器密钥,当它在N秒后过期时,我们将设置实际密钥。 我们如何知道密钥是否已过期? subscribing to redis expire events可以做到这一点。
  

当将密钥设置为过期时,EXPIRE会生成一个过期事件,或者每次在密钥上设置正超时导致删除密钥时,就会生成一个过期事件(有关更多信息,请参阅EXPIRE文档)。

  1. 一种更简单的方法(不必花很多时间进行同步工作)是使用诸如Celery之类的任务队列,并创建一个设置所需密钥的Python方法。 Celery允许诸如delayapply_async之类的装饰器和方法将任务排入队列N秒钟,然后执行发布,以便在N秒钟后将密钥设置为redis。
  

apply_async(args = None,kwargs = None,task_id = None,producer = None,   link = None,link_error = None,shadow = None,** options)[源代码]应用   通过发送消息异步完成任务。

     

参数:
   args(Tuple)–传递给   任务。

     

kwargs(Dict)–传递给任务的关键字参数。

     

倒数(浮动)–任务执行到未来的秒数   应该执行。默认为立即执行。

答案 1 :(得分:0)

最后,我使用以下方式:

首先定义一种方法来删除Redis中的密钥

r是class Country(AbstractCountry): pass connect_default_signals(Country) class Region(AbstractRegion): pass connect_default_signals(Region) class City(AbstractCity): timezone = models.CharField(max_length=40) connect_default_signals(City) class Profile(models.Model): class Meta: ordering = ('user',) verbose_name = 'Profile' verbose_name_plural = 'Profiles' GENDER_CHOICES = ( ('m', 'Male'), ('f', 'Female'), ('o', 'Other'), ('n', 'Not Specified') ) user = models.OneToOneField(User, on_delete=models.CASCADE) dob = models.DateField(blank=True, null=True, help_text='Your date of birth') gender = models.CharField(max_length=9, choices=GENDER_CHOICES, blank=True, null=True) mail_notifications_allowed = models.BooleanField(default=True, help_text='Get all your notifications via mail') newsletter = models.BooleanField(default=True, help_text='Get notifications our new services and features') use_gravtar = models.BooleanField(default=False, help_text='One avatar to rule them all!') beta_user = models.BooleanField(default=False, help_text='Test and help us find bugs in our unreleased features') avatar = models.URLField(null=True, blank=True, help_text='Profile picture URL') avatar_small = models.URLField(null=True, blank=True, help_text='Profile picture smaller URL') country = models.ForeignKey(Country, null=True, blank=True, on_delete=models.PROTECT) 实例

redis.StrictRedis

在主程序中,我设置了一个键来重命名警报和值代码,并触发线程调用remove_alarm

def remove_alarm(code, alarm_last): # alarm_last means how many seconds the key will keep alive
    time.sleep(alarm_last)
    r.srem('alarms', code)

尽管关键的“警报”将保持比r.sadd('alarms', code) # for code, it a paramater to my function threading.Thread(target=remove_alarm, args=(code, alarm_last)).start() 更长的寿命(启动线程将需要一些时间),但这对我很有用。