2014-09-09 3 views
2

Я пытаюсь написать систему производителей/потребителей, использующую Redis в C#. Каждое созданное сообщение должно потребляться только одним потребителем, и я хочу, чтобы потребители дождались элементов, созданных потребителем. Моя система должна поддерживать множество производимых/потребительских наборов.StackExchange.Redis ListRightPop не ждет результата

Я использую StackExchange.Redis для связи с Redis и с использованием списков, в которых элементы добавляются с помощью ListLeftPush и удаляются ListRightPop. То, что я испытываю, заключается в том, что, хотя метод ListRightPop должен блокироваться до тех пор, пока элемент не будет присутствовать в списке (или после определенного таймаута), он всегда возвращается автоматически, если в списке нет элементов. Это тестовый код, который я написал, чтобы проверить это:

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

И я получаю nil результат после того, как менее чем за 1 секунду.

ответ

4

Стандартные поп-операции не блокируются: они возвращают нуль, если список пуст или не существует.

SE.Redis - это мультиплексор. Использование блокирующего поп - очень плохая идея. Это объясняется более подробно с обходными решениями, специально предназначенными для блокировки всплывающих окон, в документации: https://stackexchange.github.io/StackExchange.Redis/PipelinesMultiplexers

+0

Как обычно, лучше всего перейти прямо к источнику. – welegan

+0

Марк - спасибо за указатель и за отличную рамку! Попробуй это. Тем не менее, это означает, что мы выполняем две круглые поездки на сервер кеша? Значительно уменьшает производительность решения :-( – vainolo

+0

@vainolo нет, это не значит, что особенно, если вы «стреляете и забываете» трансляцию. Они очень хорошо контактируют. Что касается паба/sub вообще: это удивительно быстро - это то, как мы приводим в действие наш сервер веб-сокетов для живых обновлений здесь, в stackoverflow, который имеет 6-значное число подключенных клиентов. –

2

StackExchange.Redis просто попадает на открытый API сервера redis, соответствующий метод которого равен BRPOP в вашем случае. Документация для этого является:

http://redis.io/commands/blpop - блокировка левую поп-

http://redis.io/commands/brpop - блокировка правого попа

В то время как эти методы делают описать поведение блокировки вы ищете, я считаю, SE.Redis ListRightPop звонит

http://redis.io/commands/rpop - правый поп

Я не могу быть до последнего пакета SE.Redis, но IntelliSense не дает мне вариант для подачи таймаута, как вы утверждаете. Кроме того, не существует методов, начинающихся с .List в интерфейсе IDatabase, в котором есть слово «блок», поэтому я не уверен, что SE.Redis предоставляет API Redis BRPOP. Вы можете написать свой собственный или попросить Марка Гравелла, но это довольно большой запрос, который я думаю из-за блокирующего характера вызова и способа работы мультиплексора.

+0

Хороший ответ. Чисто для вашего интереса, здесь подробно обсуждаются блокирующие высказывания: https://github.com/StackExchange/StackExchange.Redis/blob/master/Docs/PipelinesMultiplexers.md –

Смежные вопросы