StackExchange.Redis中的ListRightPop不等待结果

4

我正在尝试使用Redis在C#中编写生产者/消费者系统。每个消息只能由一个消费者消费,并且我希望消费者等待其他消费者创建的元素。我的系统必须支持许多生产/消费者集。

我正在使用StackExchange.Redis与Redis进行通信,使用列表(lists)来添加元素使用ListLeftPush并使用ListRightPop将其移除。我发现当应该阻塞直到列表中存在元素(或超时后),ListRightPop方法总是会自动返回,如果列表中没有元素。这是我编写用于检查此问题的测试代码:

IDatabase cache = connection.GetDatabase();        
Trace.TraceInformation("waiting "+DateTime.Now);
var res = cache.ListRightPop("test");
Trace.TraceInformation("Got "+res+", Ended" + DateTime.Now);

不到1秒钟,我就得到了nil的结果。

2个回答

7

像往常一样,最好直接去寻找源头。 - welegan
Marc - 感谢你的指引和出色的框架!我会试一下。不过,这是否意味着我们要执行两次往返到缓存服务器?这大大降低了解决方案的性能 :-( - vainolo
@vainolo 不,这并不意味着这样 - 尤其是如果你“发射并忘记”广播。它们非常流畅。至于发布/订阅的一般情况:它的速度惊人快速 - 这就是我们在Stack Overflow上为实时更新提供动力的WebSockets服务器,连接客户端数量达到六位数。 - Marc Gravell
很酷,@MarcGravell。非常感谢! - vainolo
@MarcGravell 在阅读回复并进行一些思考后 - 我认为我已经完全实现了这个async + john request <--> response。这是一个可行的解决方案吗? - Royi Namir
显示剩余10条评论

2

StackExchange.Redis只是访问redis服务器的API,您所需要使用的相关方法是BRPOP。相关文档如下:

http://redis.io/commands/blpop - 从列表左边移除元素(阻塞式)

http://redis.io/commands/brpop - 从列表右边移除元素(阻塞式)

虽然这些方法确实描述了您所寻求的阻塞行为,但我认为SE.Redis的ListRightPop调用的是以下方法:

http://redis.io/commands/rpop - 从列表右边移除元素

我可能没有使用最新版本的SE.Redis包,但智能提示并没有给我提供像您所说需要超时参数的选项。此外,在IDatabase接口中似乎没有以.List开头且包含“block”单词的方法,因此我不确定SE.Redis是否公开Redis BRPOP API。您可以自己编写代码或者友好地询问Marc Gravell,但由于调用阻塞的本质和复用器的工作方式,这是一个相当大的请求。


好的回答。纯粹为了你的兴趣,阻塞弹出窗口在这里被广泛讨论:https://github.com/StackExchange/StackExchange.Redis/blob/master/Docs/PipelinesMultiplexers.md - Marc Gravell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接