我是Redis的新手,并且想知道是否有办法能够{Key}密钥存在之前await
get
一个值。最小代码:
async def handler():
data = await self._fetch(key)
async def _fetch(key):
return self.redis_connection.get(key)
如您所知,如果此类key
不存在,则return
为None
。但是因为在我的项目中,set
密钥值对redis发生在另一个应用程序中,我希望redis_connection get
方法阻止直到存在的密钥。
这样的期望是否有效?
答案 0 :(得分:2)
您最接近此行为的方法是启用keyspace notifications并订阅相关频道(可能是模式)。
但请注意,通知依赖于不保证传递消息的PubSub(最多一次语义)。
答案 1 :(得分:2)
如果不在客户端上实现某种类型的 redis GET ,就无法做您想做的事情。在这种情况下,您的客户必须执行以下操作:
//<<DEBUG 2>>
但是,我会要求您完全重新考虑您正在使用此模式的模式。 在我看来,你需要做什么来做Pub / Sub https://redis.io/topics/pubsub。
执行 SET 的应用程序成为发布者,执行 GET 并等待密钥可用的应用程序成为订阅者。
我对此做了一些研究,看起来你可以用asyncio_redis做到这一点:
希望这会有所帮助。
答案 2 :(得分:1)
除了@Itamar Haber提到的密钥空间通知方法之外,另一个解决方案是LIST
上的阻止操作。
handler
方法在空BRPOP
:LIST
上调用BRPOP notify-list timeout
,并阻止notify-list
非空。LIST
:SET key value; LPUSH notify-list value
。handler
使用您想要的值从阻止操作中唤醒,Redis会自动销毁notify-list
。此解决方案的优点是您不需要过多地修改handler
方法(使用键空间通知解决方案,您需要注册回调函数)。虽然缺点是您必须依赖另一个应用程序的通知(使用密钥空间通知解决方案,Redis会自动执行通知)。
答案 3 :(得分:1)
Redis 5.0之后,有内置的流支持阻塞读取。以下是带有redis-py的示例代码。
#add value to my_stream
redis.xadd('my_stream',{'key':'str_value'})
#read from beginning of stream
last_id='0'
#blocking read until there is value
last_stream_item = redis.xread({"my_stream":last_id},block=0)
#update last_id
last_id = last_stream_item[0][1][0][0]
#wait for next value to arrive on stream
last_stream_item = redis.xread({"my_stream":last_id},block=0)